- 浅拷贝:简单的赋值拷贝操作
- 深拷贝:在堆区重新申请空间,进行拷贝操作
- 如果属性是在堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题。
示例:在类中成员属性定义一个指针成员(下面程序中的 int* m_height; ),在有参构造函数中,利用new在堆区开辟一个空间,让该指针指向这个内存,完成赋值。若用户自己不定义拷贝赋构造函数,使用编译器定义的浅拷贝函数会出现重复释放内存空间的问题。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include<iostream> using namespace std; class Person { public: Person() { cout << "Person 的默认构造函数调用。" << endl; } Person(int a,int height) { age = a; m_height = new int(height); cout << "Person 的有参构造函数调用。" << endl; } ~Person() { if (m_height != NULL) { delete m_height; m_height = NULL; } cout << "Person 的析构函数调用。" << endl; } int age; int* m_height; }; void test01() { Person p1(19,160); cout << "p1的年龄" << p1.age <<" 身高为:"<< *p1.m_height << endl; Person p2(p1); cout << "p2的年龄" << p2.age << " 身高为:" << *p2.m_height << endl; } int main() { test01(); return 0; }
|
注解:根据栈先入后出的规则,先析构P2,此时地址为0x0011所指向的内存已经释放,然后析构P1的时候便引发堆区的内存重复释放。
解决方法:深拷贝
示例:用户定义自己的深拷贝构造函数,也就是利用new 重新开辟一个新的空间
1 2 3 4 5 6 7
| Person(const Person& p) { cout << "Person的拷贝构造函数的调用" << endl; age = p.age; m_height = new int(*p.m_height); }
|
注解:拷贝时指向了另外一个内存,便不会出现重复释放内存的问题了