c++浅拷贝与深拷贝

来源:互联网 发布:ps软件怎么修改文字 编辑:程序博客网 时间:2024/06/16 11:50

什么是拷贝构造函数?
首先,关于c++拷贝构造函数:拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量。
对于一个类X, 如果一个构造函数的第一个参数是下列之一:

   a) X&   b) const X&   c) volatile X&   d) const volatile X&

且没有其他参数或其他参数都有默认值,那么这个函数是拷贝构造函数。可见,一个类中可以存在超过一个拷贝构造函数。

什么情况下会调用拷贝构造函数?
凡是定义新对象的语句,一定会调用构造函数:拷贝构造函数or构造函数

string a("China");//构造函数string b = a;//拷贝构造函数string c(a);//拷贝构造函数string d;//构造函数d = a;//赋值运算符

归纳起来,拷贝构造函数被调用有如下3种情况:
(1)一个对象以值传递的方式传入函数体
(2)一个对象以值传递的方式从函数返回
(3)一个对象需要通过另外一个对象进行初始化。

什么是浅拷贝?
所谓浅拷贝,指的是在对象复制时,只对对象中的数据成员进行简单的赋值,默认拷贝构造函数执行的就是浅拷贝。大多情况下“浅拷贝”已经能很好地工作了,但是一旦对象存在了动态成员,那么浅拷贝就会出问题了,对于动态指针对象,如果只是进行简单的赋值的话,那么两个指针将指向堆里的同一个对象,在销毁对象时,两个对象的析构函数将对同一个内存空间释放两次,会发生重析构。对同一块动态内存执行2次以上释放的结果是未定义的,所以这将导致内存泄露或程序崩溃。

对于赋值运算符,在对象含有堆空间的申请与释放时,也需要自行定义,不能够使用系统默认的。因为系统默认生成的赋值运算符也是浅拷贝

什么是深拷贝?
相对于浅拷贝对于任何对象都是位拷贝的方式,深拷贝对于动态分配的对象,会重新分配资源,就不会出现重析构/野指针 的问题了。当拷贝对象中有对其他资源(如堆、文件、系统等)的引用时(引用可以是指针或引用)时,对象的另开辟一块新的资源,而不再对拷贝对象中有对其他资源的引用的指针或引用进行单纯的赋值。

避免浅拷贝
如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝。位拷贝又称浅拷贝。
自定义拷贝构造函数是一种良好的编程风格,它可以阻止编译器形成默认的拷贝构造函数,提高源码效率。

原创粉丝点击