菱形继承,虚继承,STL

C++的4个子集

C子集
class子集
STL
template模板
//函数重载参数的类型或者个数不同,在C11里面也可以根据你的作之和右值来判断
void fun(int& a)//左值引用
{
	cout << "fun(int & a)" << endl;
}
void fun(const int& a)//万能引用不管你是左值还是右值
{
	cout << "fun(const int &a)" << endl;
}
void fun(int&& a)//右值引用
{
	cout << "fun(int && a)" << endl;
}
int main()
{
	int a = 10;
	const int b = 20;
	const int& x = b;
	const int& y = 20;
	fun(x);
	fun(y);
	fun(10);
	return 0;
}

在这里插入图片描述
void fun(const int& a)//常引用不管你是左值还是右值都以引用

//函数重载参数的类型或者个数不同,在C11里面也可以根据你的作之和右值来判断
void fun(int& a)//左值引用
{
	cout << "fun(int & a)" << endl;
}
void fun(const int& a)//万能引用不管你是左值还是右值
{
	cout << "fun(const int &a)" << endl;
}
//void fun(int&& a)//右值引用
//{
//	cout << "fun(int && a)" << endl;
//}
int main()
{
	int a = 10;
	const int b = 20;
	const int& x = b;
	const int& y = 20;
	fun(x);
	fun(y);
	fun(10);//首先找右值引用,其次是找常引用函数
	return 0;
}

在这里插入图片描述

void fun(int& a)//左值引用
{
	cout << "fun(int & a)" << endl;
}
void fun(const int& a)//万能引用不管你是左值还是右值
{
	cout << "fun(const int &a)" << endl;
}
void fun(int&& a)//右值引用
{
	cout << "fun(int && a)" << endl;
}
template<class T>
void fac(T&& a)//右值一旦拥有名字将变为左值
{
	fun(a);
}
int main()
{
	int a = 10;
	const int b = 20;
	fac(a);
	fac(b);
	fac(20);
	return 0;
}

在这里插入图片描述

完美转发 std::forward(a)

系统为了避免上述的右值引用的情况产生了新的概念完美转发

void fun(int& a)//左值引用
{
	cout << "fun(int & a)" << endl;
}
void fun(const int& a)//万能引用不管你是左值还是右值
{
	cout << "fun(const int &a)" << endl;
}
void fun(int&& a)//右值引用
{
	cout << "fun(int && a)" << endl;
}
template<class T>
void fac(T&& a)//右值一旦拥有名字将变为左值
{
	//fun(a);
	fun(std::forward<T>(a));
}
int main()
{
	int a = 10;
	const int b = 20;
	fac(a);
	fac(b);
	fac(20);
	return 0;
}

在这里插入图片描述

template<class T>
class Object
{
	T value;
public:
	Object(T x = T()) :value(x) {}
	static int num;
};
template<class T>
int Object<T>::num = 0;
class Base :public Object<int>
{
public: Base() { num += 1; }
	  void Print()const { cout << "Base" << num<<endl; }
};
class Test :public Object<int>
{
public:
	Test() { num += 1; }
	void Print()const { cout << "Test" << num << endl; }
};
int main()
{
	Base b1, b2;
	Test t1, t2;
	b1.Print();
	t1.Print();
	return 0;
}

在这里插入图片描述

template<class T>
class Object
{
	T value;
public:
	Object(T x = T()) :value(x) {}
	static int num;
};
template<class T>
int Object<T>::num = 0;
class Base :public Object<int>
{
public: Base() { num += 1; }
	  void Print()const { cout << "Base" << num<<endl; }
};
class Test :public Object<double>
{
public:
	Test() { num += 1; }
	void Print()const { cout << "Test" << num << endl; }
};
int main()
{
	Base b1, b2;
	Test t1, t2;
	b1.Print();
	t1.Print();
	return 0;
}

在这里插入图片描述

菱形继承

菱形继承的概念:

两个不同的派生类继承于同一个父类,又有一个子类多继承于这个两个派生类。 数据冗余导致的不一致性

class Person
{
private:
	string p_id;
	string p_name;
	string p_sex;
	int p_age;
public:
	Person(const string& id, const string& name, const string& sex, int age)
		:p_id(id), p_name(name), p_sex(sex), p_age(age)
	{}
	void print()const
	{
		cout << "id:   " << p_id << endl;
		cout << "name: " << p_name << endl;
		cout << "sex:  " << p_sex << endl;
		cout << "age:  " << p_age << endl;
	}
};
class Student :public Person
{
private:
	string s_id;
public:
	Student(const string& id, const string& name, const string& sex, int age, const string& d)
		:Person(id, name, "男", age), s_id(d)
	{}
};
class Staff :public Person
{
private:
	string s_id;
public:
	Staff(const string& id, const string& name, const string& sex, int age, const string& d)
		:Person(id, name, "女", age), s_id(d)
	{}
};
class Stud_Staff :public Student, public Staff
{
private:
public:
	Stud_Staff(const string& id, const string& name, int age, const string& dd, const string ss)
		:Student(id,name,"男",age,ss),Staff(id,name,"nv",age,dd)
	{

	}
};
int main()
{

	Stud_Staff ss("610431199900000000", "王伟", 23, "20200", "303030");
	ss.Student::print();
	ss.Staff::print();
	Student s1 = ss;
	Staff s2 = ss;
	//Person p = ss;erro因为此类里面有两个人//数据冗余导致的不一致性
	return 0;
}

在这里插入图片描述
在这里插入图片描述

虚继承

虚继承定义:

在继承体结构下,将其成员数据实例共享给也从这个基类型直接或间接派生的其它类。

虚继承就是为了解决菱形继承的缺陷
基类A B虚继承A,C虚继承A D公有继承B,C这时可以再D里面直接继承A里面的属性,避免BC二义性
解决上述多重继承导致的数据冗余下使用虚继承可以有效的使得D即Stud_Staff 直接从A即Person那里继承;注意一旦这样,如果通过D调用B和C里面的成员方法但凡涉及到A的成员,B和C里面分别会与一个指针分别指向新的A(D中构建的一个)
注意若BC不虚继承A,D这里不能直接继承,因为:不允许使用间接非虚拟机类

class Person
{
private:
	string p_id;
	string p_name;
	string p_sex;
	int p_age;
public:
	Person(const string& id, const string& name, const string& sex, int age)
		:p_id(id), p_name(name), p_sex(sex), p_age(age)
	{}
	void print()const
	{
		cout << "id:   " << p_id << endl;
		cout << "name: " << p_name << endl;
		cout << "sex:  " << p_sex << endl;
		cout << "age:  " << p_age << endl;
	}
};
class Student : virtual public Person
{
private:
	string s_id;
public:
	Student(const string& id, const string& name, const string& sex, int age, const string& d)
		:Person(id, name, "男", age), s_id(d)
	{}
};
class Staff :virtual public Person
{
private:
	string s_id;
public:
	Staff(const string& id, const string& name, const string& sex, int age, const string& d)
		:Person(id, name, "女", age), s_id(d)
	{}
};
class Stud_Staff :public Student, public Staff
{
private:
	int num = 10;
public:
	Stud_Staff(const string& id, const string& name, int age, const string& dd, const string ss)
		:Student(id,name,"男",age,ss),Staff(id,name,"女",age,dd)
	,Person("61010","yhping","男",23)
	{
	}
};
int main()
{

	Stud_Staff ss("610431199900000000", "王伟", 23, "20200", "303030");
	ss.Student::print();
	ss.Staff::print();
	Student s1 = ss;
	Staff s2 = ss;
	Person p = ss;
	return 0;
}

在这里插入图片描述

class Object
{
	int value;
public:
	Object(int x = 10) :value(x) {}
 };
class Base :virtual public Object
{
	int num;
public:
	Base(int x = 0) :num(x), Object(x + 10) {}
};
class Test :virtual public Object
{
	int sum;
public:
	Test(int x = 0) :sum(x), Object(x + 10) {}
};
class Det :public Base, public Test
{
private:
	int total;
public:
	Det(int x = 0) :total(x), Base(x + 10), Test(x + 20), Object(x + 100) {}
};
int main()
{
	Det d(0);
	return 0;
}

这样一旦通过D来调用B和C里面的公有方法涉及到A的部分就会完全由新产生的Object去代替B和C里面有指针直接指向新的Object
在这里插入图片描述

菱形继承的多继承

class Object
{
	int value;
public:
	Object(int x = 10) :value(x) {}
	virtual void fun() { cout << "Object" << endl; }
	virtual void add() { cout << "Object::add" << endl; }
 };
class Base :public Object
{
	int num;
public:
	Base(int x = 0) :num(x), Object(x + 10) {}
	virtual void fun() { cout << "Base" << endl; }
};
class Test : public Object
{
	int sum;
public:
	Test(int x = 0) :sum(x), Object(x + 10) {}
	virtual void fun() { cout << "Test" << endl; }
	 void add() { cout << "Test::add" << endl; }
};
class Det :public Base, public Test
{
private:
	int total;
public:
	Det(int x = 0) :total(x), Base(x + 10), Test(x + 20) {}
	 void fun() { cout << "Det" << endl; }
	void add() { cout << "Det::add" << endl; }
};
int main()
{
	Det d(0);
	//Object* op = &d;erro因为d里面Base和Test都有Object
	Object* opa = (Base*)&d;
	Object* opb = (Test*)&d;//opa和opb 是不同的地址
	opa->add();
	opa->fun();

	opb->add();
	opb->fun();
	return 0;
}

在这里插入图片描述

在这里插入图片描述

虚继承的多继承

class Object
{
	int value;
public:
	Object(int x = 10) :value(x) {}
	virtual void fun() { cout << "Object" << endl; }
	virtual void add() { cout << "Object::add" << endl; }
 };
class Base :virtual public Object
{
	int num;
public:
	Base(int x = 0) :num(x), Object(x + 10) {}
	virtual void fun() { cout << "Base" << endl; }
};
class Test : virtual public Object
{
	int sum;
public:
	Test(int x = 0) : sum(x), Object(x + 10) {}
	virtual void fun() { cout << "Test" << endl; }
	 void add() { cout << "Test::add" << endl; }
};
class Det :public Base, public Test
{
private:
	int total;
public:
	Det(int x = 0) :total(x), Base(x + 10), Test(x + 20), Object(x + 100) {}
	 void fun() { cout << "Det" << endl; }
	void add() { cout << "Det::add" << endl; }
};
int main()
{
	Det d(0);
	Object* opa = &d;
	Object* opb = &d;//opa和opb 是不同的地址
	opa->add();
	opa->fun();

	opb->add();
	opb->fun();
	return 0;
}

在这里插入图片描述

STL

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

STL问的最多的就是配置器和迭代器的失效问题
在这里插入图片描述

字符串库

#include<string>//c++里面的字符串类型
#include<string.h>//C库里面的字符串函数库
#include<cstring>//C库里面的字符串函数库
int main()
{
	string s1 = "yhpingll";
	string s2("yhpingll");
	//string::value_type p;
	string::value_type v;//char v
	string::pointer p = &v;
	string::reference x = v;
	//char&x=v;
	string::const_reference y = v;
	//char const&y=v;

	cout << typeid(p).name() << endl;

}
int main()
{
	string s1 = "abcdefgh";
	string::iterator it = s1.begin();
	for (;it != s1.end(); ++it)
	{
		cout << *it;
	}
	cout << endl;
	string::reverse_iterator rt;
	for (rt = s1.rbegin(); rt != s1.rend(); ++rt)
	{
		cout << *rt;
	}
	cout << endl;
	for (auto& x : s1)
	{
		cout << x;
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

int main()
{
	string s1("yhping");
	string s2("hello");
	cout << s1 << endl;
	cout << s2 << endl;
	s1 = s2;
	cout << s1 << endl;//底层已经对输出流进行了重载
	cout << s2 << endl;
}

在这里插入图片描述

int main()
{
	string s1("yhping");
	string s2("hello");
	cout << s1 << endl;
	cout << s2 << endl;
	s1 = std::move(s2);
	cout << s1 << endl;//底层已经对输出流进行了重载
	cout << s2 << endl;
}

在这里插入图片描述

#include<string>//c++里面的字符串类型
int main()
{
	string s1("yhping");
	cout << "size: " << s1.size() << endl;
	cout << "capacity: " << s1.capacity() << endl;
	s1 += "hellohelloniahoanihaoa";
	cout << "size: " << s1.size() << endl;
	cout << "capacity: " << s1.capacity() << endl;
	return 0;
}

在这里插入图片描述

int main()
{
	string s1("yhping");
	int n = s1.size();
	for (int i = 0; i < n; ++i)
	{//下标访问
		cout << s1[i] << " ";
	}
	cout << endl;
	//在某些STL库里面[]访问并不检查是否越界,函数检查是否越界
	for (int i = 0; i < n; ++i)
	{//函数访问
		cout << s1.at(i) << " ";
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

int main()
{
	string s1("yhping");
	char cha = s1[1];

	char& chb = s1[1];//一般情况下不要以引用接收

	s1.clear();//清除函数
	s1 = "hello";
	cout << chb << endl;

	return 0;
}

在这里插入图片描述

int main()
{
	string s1("yhping");
	cout << "size: " << s1.size() << endl;
	cout << "Capt: " << s1.capacity() << endl;
	cout << "max_size: "<<s1.max_size() <<endl;
	s1.reserve(128);
	cout << "size: " << s1.size() << endl;
	cout << "Capt: " << s1.capacity() << endl;
	cout << "max_size: " << s1.max_size() << endl;
}

在这里插入图片描述

int main()
{

	string s1("yhping");
	cout << s1.size() << " " << s1.capacity() << endl;
	s1.reserve(200);//正常情况每一次空间不够的时候扩容,我们现在直接一次性给200个字节空间,不需要反复的对空间进行操作
	for (int i = 0; i < 10; ++i)
	{
		s1 += "hello";
		cout << s1.size() << " " << s1.capacity() << endl;
	}
}

在这里插入图片描述

#include<vector>
class Object
{
private:
	int value;
public:
	Object(int x = 0) :value(x) { cout << "Object" << endl; }
	Object(const Object& obj) :value(obj.value) { cout << "Object &" << endl; }
	Object(Object&& obj) :value(obj.value) { cout << "move Object&&" << endl; }
	Object& operator=(const Object& obj)
	{
		value = obj.value;
		cout << "operator=" << endl;
		return *this;
	}
	Object& operator=(const Object&& obj)
	{
		value = obj.value;
		cout << "operator=" << endl;
		return *this;
	}
	~Object()
	{
		cout << "~Object" << endl;
	}
};
int main()
{
	vector<Object> vecobj;

	for (int i = 0; i < 5; ++i)
	{
		vecobj.push_back(Object(10));
		cout << vecobj.size() << endl;
		cout << vecobj.capacity() << endl;
	}
	return 0;
}

反复的扩容导致产生更多的构造和析构函数并且产生了更多的对象
增空间将原来的对象挪到新空间,在释放原来的旧空间
在这里插入图片描述

int main()
{
	vector<Object> vecobj;
	vecobj.reserve(200);
	for (int i = 0; i < 5; ++i)
	{
		vecobj.push_back(Object(10));
		cout << vecobj.size() << endl;
		cout << vecobj.capacity() << endl;
	}
	return 0;
}

在这里插入图片描述

随机性迭代器和双向迭代器的区别

int main()
{
	vector<int>ivec = { 12,2,3,34,45 };
	//随机性迭代器
	vector<int>::iterator it = ivec.begin();
	it++;
	it += 5;
	list<int>ilist = { 12,2,3,34,45 };
	//双向迭代器
	list<int>::iterator i = ilist.begin();
	i++;
	i += 5;//Erro链表不能
	return 0;
}
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值