深拷贝与浅拷贝(3)

浅拷贝:简单的赋值拷贝操作,编译器提供的拷贝构造函数

深拷贝:在堆区重新申请空间,进行拷贝操作,程序员提供

浅拷贝:

如果利用编译器提供的拷贝构造函数,会做浅拷贝操作。

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class Person
 5 {
 6 public:
 7 
 8     Person()
 9     {
10         cout << "Person默认构造函数的调用" << endl;
11     }
12 
13     Person(int age,int height)
14     {
15         m_Age = age;
16         m_Height = new int(height);  //指针来接收
17         cout << "Person有参构造函数的调用" << endl;
18     }
19 
20     ~Person()
21     {
22         //if (m_Height != NULL)
23         //{
24             //delete m_Height;
25             //m_Height = NULL;
26         //}
27         cout << "Person析构函数的调用" << endl;
28     }
29 
30     int m_Age;
31     int *m_Height;  //堆区数据要用指针来接收
32 
33 };
34 
35 void test_01()
36 {
37     Person p1(18, 160);
38 
39     cout << "p1的年龄: " << p1.m_Age << " p1的身高: " << *p1.m_Height << endl;
40     
41     Person p2(p1);
42 
43     cout << "p2的年龄: " << p2.m_Age << " p2的身高: " << *p2.m_Height << endl;
44 }
45 
46 int main(void)
47 {
48     test_01();
49 
50     system("pause");
51     return 0;
52 }

堆区开辟的数据,由程序员手动开辟,也要由程序员手动释放。

什么时候释放呢?在对象被销毁之前释放,对象什么时候被销毁呢?程序执行结束之前。程序执行结束之前会调用什么函数呢?析构函数!

析构函数终于排上用场了~~~~

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class Person
 5 {
 6 public:
 7 
 8     Person()
 9     {
10         cout << "Person默认构造函数的调用" << endl;
11     }
12 
13     Person(int age,int height)
14     {
15         m_Age = age;
16         m_Height = new int(height);
17         cout << "Person有参构造函数的调用" << endl;
18     }
19 
20     ~Person()
21     {
22         if (m_Height != NULL)  //释放
23         {
24             delete m_Height;
25             m_Height = NULL;
26         }
27         cout << "Person析构函数的调用" << endl;
28     }
29 
30     int m_Age;
31     int *m_Height;
32 
33 };
34 
35 void test_01()
36 {
37     Person p1(18, 160);
38 
39     cout << "p1的年龄: " << p1.m_Age << " p1的身高: " << *p1.m_Height << endl;
40     
41     Person p2(p1);
42 
43     cout << "p2的年龄: " << p2.m_Age << " p2的身高: " << *p2.m_Height << endl;
44 }
45 
46 int main(void)
47 {
48     test_01();
49 
50     system("pause");
51     return 0;
52 }

运行上述代码,观察一下:

 

 是什么原因造成的呢?我们来分析一下:

 1 void test_01()
 2 {
 3     Person p1(18, 160);
 4 
 5     cout << "p1的年龄: " << p1.m_Age << " p1的身高: " << *p1.m_Height << endl;
 6     
 7     Person p2(p1);
 8 
 9     cout << "p2的年龄: " << p2.m_Age << " p2的身高: " << *p2.m_Height << endl;
10 }

栈区的数据先进后出:编译器会先执行p2的析构函数,然后再执行p1的析构函数。换句话说:就是堆区的数据已经被p2的析构函数释放了,p1就没有权限

去访问了!

 

 总结:如果使用浅拷贝的话,会造成堆区的数据重复释放,系统会报错。

 

深拷贝:

专门用来解决浅拷贝带来的问题。

思路:

自己写自己拷贝构造函数,在拷贝构造函数中重新为 m_Height 在堆区开辟一个空间,这样问题就解决了。

 

 

 

 

 

代码实现:

 1 //拷贝构造函数
 2     Person(const Person &p)
 3     {
 4         m_Age = p.m_Age;
 5         //m_Height = p.m_Height;//编译器默认实现的就是这行代码,结果造成浅拷贝的问题
 6         //深拷贝的操作
 7         m_Height = new int(*p.m_Height);
 8 
 9         cout << "Person拷贝构造函数的调用" << endl;
10     }

再次运行就没有问题了。

 

posted @ 2020-04-12 11:19  坦率  阅读(155)  评论(0编辑  收藏  举报