转载自:https://blog.csdn.net/u010700335/article/details/39830425

C++中类的拷贝有两种:深拷贝,浅拷贝:当出现类的等号赋值时,即会调用拷贝函数
一:两个的区别
1 在未定义显示拷贝构造函数的情况下,系统会调用默认的拷贝函数——即浅拷贝,它能够完成成员的一一复制。当数据成员中没有指针时,浅拷贝是可行的;但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针将指向同一个地址,当对象快结束时,会调用两次析构函数,而导致指针悬挂现象,所以,此时,必须采用深拷贝。
2 深拷贝与浅拷贝的区别就在于深拷贝会在堆内存中另外申请空间来储存数据,从而也就解决了指针悬挂的问题。简而言之,当数据成员中有指针时,必须要用深拷贝。
二  带实例的解释
c++默认的拷贝构造函数是浅拷贝
浅拷贝就是对象的数据成员之间的简单赋值,如你设计了一个没有类而没有提供它的复制构造函数,当用该类的一个对象去给令一个对象赋值时所执行的过程就是浅拷贝,如:
class A
{
public:
A(int _data) : data(_data){}
A(){}
private:
int data;
};
int main()
{
A a(), b = a; // 仅仅是数据成员之间的赋值
}
这一句b = a;就是浅拷贝,执行完这句后b.data = 5;
如果对象中没有其他的资源(如:堆,文件,系统资源等),则深拷贝和浅拷贝没有什么区别,
但当对象中有这些资源时,例子:
class A
{
public:
A(int _size) : size(_size)
{
data = new int[size];
} // 假如其中有一段动态分配的内存
A(){};
~A()
{
delete [] data;
} // 析构时释放资源
private:
int* data;
int size;
}
int main()
{
A a(), b = a; // 注意这一句
}
这里的b = a会造成未定义行为,因为类A中的复制构造函数是编译器生成的,所以b = a执行的是一个浅拷贝过程。我说过浅拷贝是对象数据之间的简单赋值,比如:
b.size = a.size;
b.data = a.data; // Oops!
这里b的指针data和a的指针指向了堆上的同一块内存,a和b析构时,b先把其data指向的动态分配的内存释放了一次,而后a析构时又将这块已经被释放过的内存再释放一次。对同一块动态内存执行2次以上释放的结果是未定义的,所以这将导致内存泄露或程序崩溃。
所以这里就需要深拷贝来解决这个问题,深拷贝指的就是当拷贝对象中有对其他资源(如堆、文件、系统等)的引用时(引用可以是指针或引用)时,对象的另开辟一块新的资源,而不再对拷贝对象中有对其他资源的引用的指针或引用进行单纯的赋值。如:
class A
{
public:
A(int _size) : size(_size)
{
data = new int[size];
} // 假如其中有一段动态分配的内存
A(){};
A(const A& _A) : size(_A.size)
{
data = new int[size];
} // 深拷贝
~A()
{
delete [] data;
} // 析构时释放资源
private:
int* data;
int size;
}
int main()
{
A a(), b = a; // 这次就没问题了
}
总结:深拷贝和浅拷贝的区别是在对象状态中包含其它对象的引用的时候,当拷贝一个对象时,如果需要拷贝这个对象引用的对象,则是深拷贝,否则是浅拷贝。

最新文章

  1. 在Extjs中对日期的处理,以及在后端数据在SQL语句的判断处理
  2. 【代码笔记】iOS-改变导航条标题的颜色为红色
  3. Android实例-全屏显示程序(XE10+小米2)(无图)
  4. 初识FreeMarker
  5. CentOS 6.4 通过Yum给Chrome安装Adobe Flash Player
  6. healthkit 记录每天用户的运动情况
  7. IT项目经理应具备的十大软技能
  8. apache也可以做负载均衡,跟nignx的区别是什么?
  9. UIImage图片处理
  10. Lightdm:奔跑吧GUI[已解决]
  11. 签名“未签名”apk文件命令
  12. Linux中的定时任务at、crontab
  13. Socket编程实践(4) --多进程并发server
  14. P2613 有理数取余
  15. PythonStudy——高级语言 High-level programming language
  16. FJUT16级第一周寒假作业题解G题
  17. SD从零开始38-40
  18. php 命令行脚本运行php文件简单演示
  19. SpringBoot实战(十三)之缓存
  20. CSS Position(定位)

热门文章

  1. Werkzeug(Flask)之Local、LocalStack和LocalProxy
  2. 清北学堂dp图论营游记day2
  3. c++命名空间namespace
  4. js 代码位置不同,导致随着点击函数执行次数累加
  5. NOIP2017提高A组模拟10.6】Biology
  6. set -ex
  7. python web Tornado框架
  8. python 手动拼接json数据
  9. python学习之路(4)
  10. 如何使用git工具