<C++> 类(4):静态成员变量和函数 浅拷贝和深拷贝(拷贝构造 operator=)
一.静态成员变量和函数
1.静态成员变量:
①如果在类中放了静态static成员变量 一定要在源文件即.cpp中 类外 给这个变量进行初始化
初始化时要有:类型 类名 作用域
1 int CPerson::a = 100;
注意:一定要在定义CPerson类的后面初始化 不然会说不认识CPerson
②static变量在编译期的时候就存在了
不用定义对象调用 通过类名和作用域就可以调用:“类名::静态变量名” 这样就可以直接使用
③当一个类中只放了一个静态成员变量的时候 这个类的大小:sizeof(类名) = 1
但是一个类中只放了一个int类型的成员变量 那么这个类的大小:sizeof(类名) = 4
1 #include<iostream> 2 using namespace std; 3 4 class Cperson 5 { 6 public: 7 int a; 8 }; 9 10 class CPerson 11 { 12 public: 13 static int a; 14 }; 15 16 int CPerson::a = 100; 17 18 int main() 19 { 20 cout << sizeof(Cperson) << endl; 21 cout << sizeof(CPerson) <<endl; 22 }
输出结果:4 1
④定义对象不会再给static变量申请新的空间
static是属于类的 一个类的所有对象共享一个static变量
也就是说 无论一个类定义了多少了对象 对static进行操作 都是对同一个变量进行操作
1 #include<iostream> 2 using namespace std; 3 4 class CPerson 5 { 6 public: 7 static int a; 8 }; 9 10 int CPerson::a = 100; 11 12 int main() 13 { 14 CPerson ps1; 15 CPerson ps2; 16 ps1.a = 1000; 17 18 cout << ps1.a << endl; 19 cout << ps2.a << endl; 20 }
输出结果:两个输出都是1000 足以说明一个类声明的所有对象 共用一个static变量
2.静态成员函数:
①静态函数只能用static成员 不能用非静态成员(因为静态函数没有this指针)
②同样 静态函数也是没有对象就可以调用这个函数:“类名::静态函数名”直接调用
1 #include<iostream> 2 using namespace std; 3 4 class CPerson 5 { 6 public: 7 static int a; 8 int b; 9 public: 10 static void Show() 11 { 12 cout << a << endl; 13 //cout << b << endl; 14 //如果放开上面一行就会报错 因为静态成员函数只能用static成员 15 } 16 }; 17 18 int CPerson::a = 100; 19 20 int main() 21 { 22 cout << CPerson::a << endl; 23 CPerson::Show(); 24 }
二.拷贝构造
1.引入:
1 CPerson aa; 2 CPerson bb(aa);
第2行这样的语法在C++中是允许的 这就说明在类中 是有一个默认的构造函数的
2.浅拷贝:(拷贝构造函数)
1 CPerson(const CPerson& ps) 2 { 3 this -> a = ps.a; 4 }
3.深拷贝:
1 CPerson(const CPerson& ps) 2 { 3 this -> a = new int; 4 this -> a = ps.a; 5 }
4.浅拷贝和深拷贝的理解图:
①浅拷贝会出现的问题就是:在释放空间的时候 会出现一个空间删除两次的现象 会崩
所以为了避免 尽量不使用值传递 或者用深拷贝也可以解决
②完成深拷贝必须知道new出来的空间是多大的
对于我们来说 这块空间的大小和我们定义的成员有关 我们知道 但是系统不知道 所以内存默认的拷贝构造函数是浅拷贝
5.总结:
①拷贝构造:第一个参数是当前这个类的const类型的引用的构造函数 叫做拷贝构造函数
②作用:复制一个对象
③注意:类中默认的是浅拷贝 会使两个对象使用一个空间 会出现同一个空间被释放两次的问题
④解决:函数参数用指针 引用 或者使用深拷贝
所以在使用参数的时候 尽量不要直接给值 容器也一样 使用list<CPerson*> 而不是list<CPerson>
三.operator=
1.引入:
1 CPerson aa; 2 CPerson bb; 3 aa = bb;
第3行可以正常运行 就说明 系统中有一个默认的operator= 也是一个浅拷贝
2.浅拷贝:
1 CPerson& operator=(const CPerson& ps) 2 { 3 return *this; 4 }
默认的operator= 也是一个浅拷贝
3.深拷贝:
1 CPerson& operator=(const CPerson& ps) 2 { 3 delete this->a; // 创建对象的时候已经分配空间了 所以要删除原来的空间 4 5 this->a = new int; // 重新分配 6 *(this->a) = *(ps.a); 7 return *this; 8 }
4.总结:
①在空类中 有4个默认函数:构造 析构 拷贝构造 和operator=
②拷贝构造和operator=都是浅拷贝
③拷贝构造的执行时间 是在对象创建的时候 而operator=的执行时间是两个对象用“=”赋值的时候