类(4):静态成员变量和函数 浅拷贝和深拷贝(拷贝构造 operator=)

时间:2021-08-21 19:53:29

一.静态成员变量和函数

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.浅拷贝和深拷贝的理解图:

类(4):静态成员变量和函数 浅拷贝和深拷贝(拷贝构造 operator=)

①浅拷贝会出现的问题就是:在释放空间的时候 会出现一个空间删除两次的现象 会崩

所以为了避免 尽量不使用值传递 或者用深拷贝也可以解决

②完成深拷贝必须知道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=的执行时间是两个对象用“=”赋值的时候