08-1 深拷贝和浅拷贝的总结
-
深拷贝和浅拷贝的出现情况
- 在类中,且这个类的属性中有指向堆区的地址。
-
什么情况会出现深拷贝和浅拷贝
- 属性中有指向堆区的地址的类使用默认拷贝构造函数和默认赋值运算的时候会出现。
-
如何解决
- 如果是需要拷贝构造函数,则需要提供一个拷贝构造函数。
- 如果是对变量进行赋值,则需要重载赋值运算符。
-
注意事项
- 如果类中存在地址的属性,那么务必提供一个析构函数。避免堆区数据不释放。
- 在类的赋值运算中,务必在给被赋值的对象赋新值的时候释放原先已经占用的堆区内存。
- 不过不建议在类中出现地址的情况。因为这样会麻烦很多。但是如果迫不得已要使用类中含有地址,请务必注意关注是否释放内存/是否会存在非法访问的情况。
-
示例
-
拷贝构造函数
class test { public: int* p_m_A; int m_B; test() { p_m_A = new int(10); m_B = 20; } test(class test& p) { p_m_A = new int(*p.p_m_A); m_B = p.m_B; } ~test() { if (p_m_A != NULL) { delete p_m_A; p_m_A = NULL; } } };
提示:如果自定义了拷贝构造函数,那么编译器不会提供默认构造函数。
-
重载赋值运算符
class test { public: int* p_m_A; int m_B; test() { p_m_A = new int(10); m_B = 20; } ~test() { if (p_m_A != NULL) { delete p_m_A; p_m_A = NULL; } } class test& operator=(class test& p) { if (p_m_A != NULL) { delete p_m_A; p_m_A = NULL; } p_m_A = new int(*p.p_m_A); m_B = p.m_B; return *this; } };
提示:重载赋值运算符只可以在成员函数中重载。
-
:-)