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;
}
系统为了避免上述的右值引用的情况产生了新的概念完美转发
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;
}
#include //c++里面的字符串类型
#include //C库里面的字符串函数库
#include //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 //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
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;
}