【C++】 --- 深拷贝与浅拷贝

简介: 【C++】 --- 深拷贝与浅拷贝

浅拷贝:简单的赋值拷贝操作

深拷贝:在堆区重新申请空间,进行拷贝操作

 

下面程序,先不提供拷贝构造函数,用系统默认提供的拷贝构造函数

1. class Person {
2. public:
3.  //无参(默认)构造函数
4.  Person() {
5.    cout << "无参构造函数!" << endl;
6.  }
7.  //有参构造函数
8.  Person(int age ,int height) {
9. 
10.     cout << "有参构造函数!" << endl;
11. 
12.     m_age = age;
13.     m_height = new int(height); 
14.   }
15. 
16.   //析构函数
17.   ~Person() {
18.     cout << "析构函数!" << endl;
19.     if (m_height != NULL)
20.     {
21.       delete m_height;
22.     }
23.   }
24. public:
25.   int m_age;
26.   int* m_height;
27. };
28. 
29. void test01()
30. {
31.   Person p1(18, 180);
32. 
33.   Person p2(p1);
34. 
35.   cout << "p1的年龄: " << p1.m_age << " 身高: " << *p1.m_height << endl;
36. 
37.   cout << "p2的年龄: " << p2.m_age << " 身高: " << *p2.m_height << endl;
38. }
39. 
40. int main() {
41. 
42.   test01();
43. 
44.   system("pause");
45. 
46.   return 0;
47. }

在VC中运行结果如下:

之所以出现中断错误,是因为,C++编译器默认提供的构造函数如下:

1.  //拷贝构造函数  
2.  Person(const Person& p) {
3.    cout << "拷贝构造函数!" << endl;
4.    //如果不利用深拷贝在堆区创建新内存,会导致浅拷贝带来的重复释放堆区问题
5.    m_age = p.m_age;
6.    m_height = p.m_height;
7. 
8.  }

执行完person p2(p1)后的内存分布如图

p1和p2的m-heigth指针变量指向了同一块内存,在析构的 时候,p2先释放,然后p1再次释放的时候就会报错

 

所以这里我们要自己定义一个拷贝构造函数,修改如下

1.  //拷贝构造函数  
2.  Person(const Person& p) {
3.    cout << "拷贝构造函数!" << endl;
4.    //如果不利用深拷贝在堆区创建新内存,会导致浅拷贝带来的重复释放堆区问题
5.    m_age = p.m_age;
6. //m_heigth = p.m_height   C++编译器默认提供的
7.    m_height = new int(*p.m_height);
8. 
9.  }
相关文章
|
5月前
|
编译器 C++ Python
【C/C++ 泡沫精选面试题02】深拷贝和浅拷贝之间的区别?
【C/C++ 泡沫精选面试题02】深拷贝和浅拷贝之间的区别?
87 1
|
11月前
|
存储 Cloud Native Linux
C++ 深拷贝浅拷贝
C++ 深拷贝浅拷贝
|
4月前
|
存储 编译器 C++
C++进阶之路:何为拷贝构造函数,深入理解浅拷贝与深拷贝(类与对象_中篇)
C++进阶之路:何为拷贝构造函数,深入理解浅拷贝与深拷贝(类与对象_中篇)
32 0
|
4月前
|
算法 编译器 Linux
【C++/STL】:vector容器的底层剖析&&迭代器失效&&隐藏的浅拷贝
【C++/STL】:vector容器的底层剖析&&迭代器失效&&隐藏的浅拷贝
34 0
|
11月前
|
C++
22 C++ - 深拷贝和浅拷贝
22 C++ - 深拷贝和浅拷贝
39 0
|
12月前
|
编译器 C++
C++:基于浅拷贝/深拷贝对模拟string类的一些优化
C++:基于浅拷贝/深拷贝对模拟string类的一些优化
|
编译器 C++
C++中的深拷贝和浅拷贝介绍
对于基本类型的数据以及简单的对象,它们之间的拷贝非常简单,就是按位复制内存。例如: class Base{ public: Base(): m_a(0), m_b(0){ } Base(int a, int b): m_a(a), m_b(b){ } private: int m_a; int m_b; }; int main(){ int a = 10; int b = a; //拷贝 Base obj1(10, 20);
115 0
|
16天前
|
编译器 C++
C++ 类构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。
60 30
|
5天前
|
并行计算 Unix Linux
超级好用的C++实用库之线程基类
超级好用的C++实用库之线程基类
12 4
|
4天前
|
C++ Windows
HTML+JavaScript构建C++类代码一键转换MASM32代码平台
HTML+JavaScript构建C++类代码一键转换MASM32代码平台