关于C++中的深拷贝

说到深拷贝,是相对于浅拷贝而言的。弄清了浅拷贝,深拷贝也就不言自明了。对C++初学者而言,所谓浅拷贝在编写程序过程中往往是无感的。我们一般在写一个类时,多数情况我们只是写了成员变量、成员函数,有时为了赋初值方便,再写一个有参构造函数。而析构函数、拷贝构造函

数往往不写。虽然我们没有写这两个函数,但多数情况并没有影响我们在程序中完成拷贝操作。例如,我们声明一个类:

class myClass

{

public:

myClass ( int c )

{

count = c

}

int count;

}

这时,如果我们进行下面操作:

myClass mc1 ( 3 ); //声明mc1对象,并对mc1.count赋初值3

myClass mc2 ( mc1 ); //声明mc2对象,并将将mc1拷贝给mc2

以上两句代码,是能正常运行的。那么将mc1拷贝给mc2是哪个函数完成的哪?前面讲过,我们在写myClass类时,如果我们只声明成员变量,其它都不写,那么编译器会默认地给类加上三个函数:a.默认无参构造函数( 负责初始化 ); b.默认无参析构函数( 负责释放内存 ); c.默认拷贝构造函数( 对属性值进行拷贝 )。正是默认拷贝构造函数完成了将mc1拷贝给mc2的操作,这也就是所谓的浅拷贝。

如果我们把上边的类给改动一下,比如我们希望这个类生成的对象的某些属性能够生存周期足够长该怎样做呢?这时我们会引入new方法将语句 count=c 进行改造:

pCount = new int( c ); //因为new方法产生的都是指针,所以count的声明也需要改为 int* pCount,使用时解引用即可

这样,pCount指向的值在我们delete前会一直存在( 关于new的用法这里不展开 ),满足了延长生存周期的要求。但这种做法会带来一种风险,即进行浅拷贝后,一旦默认析构函数被调用,由于拷贝目标对象与源对象属性里的指针都指向同一个内存空间,析构函数会对同一堆区delete两次,造成非法操作,编译器会报错。如果程序结束前析构函数未被调用,程序也可运行,但风险仍存在。

这个风险如何排除呢?方法就是本文要介绍的深拷贝。听起来很玄,其做法简单说就是在做类声明时,自己写一个拷贝构造函数,在写赋值语句时不是单纯的复制,而是再new一次,让拷贝目标对象和源对象里的指针各有所指,不再指向同一地址。讲着复杂,还是举一个完整的例子做说明:

class myClass

{

public:

int* pCount; //类属性值

//有参构造函数用于赋初值

myClass ( int c )

{

pCount=new int(c); //在堆区开辟内存空间保存属性值(实际使用时,要记得在适当地方delete pCount)

}

//有参拷贝构造函数用于对象间复制

myClass(const myClass mc)

{

pCount=new int(*mc.pCount);//有参构造中的是一次new,这里是二次new,等于是有重新开辟了一块内存

}

//析构函数

~myClass()

{

delete pCount;

pCount=NULL;

}

}

总结以下,深拷贝是为了解决由于使用new方法给浅拷贝带来的同一块内存被delete两次的风险问题。具体方法是在类中再次使用new方法自己写拷贝构造函数。上例中还写了析构函数,写析构函数等于加上双保险。总之,这里虽没给深拷贝下具体定义,但怎样做已经讲明白了。就是自己写拷贝构造函数,给复制来的值再另new一个空间。

相关推荐
OOJO3 小时前
c++---list介绍
c语言·开发语言·数据结构·c++·算法·list
会编程的土豆5 小时前
【数据结构与算法】动态规划
数据结构·c++·算法·leetcode·代理模式
6Hzlia7 小时前
【Hot 100 刷题计划】 LeetCode 78. 子集 | C++ 回溯算法题解
c++·算法·leetcode
所以遗憾是什么呢?7 小时前
【题解】Codeforces Round 1081 (Div. 2)
数据结构·c++·算法·acm·icpc·ccpc·xcpc
白藏y7 小时前
【C++】muduo接口补充
开发语言·c++·muduo
xiaoye-duck8 小时前
《算法题讲解指南:递归,搜索与回溯算法--综合练习》--14.找出所有子集的异或总和再求和,15.全排列Ⅱ,16.电话号码的字母组合,17.括号生成
c++·算法·深度优先·回溯
OOJO8 小时前
c++---vector介绍
c语言·开发语言·数据结构·c++·算法·vim·visual studio
Tanecious.9 小时前
蓝桥杯备赛:Day5-P1706 全排列问题
c++·蓝桥杯
胖咕噜的稞达鸭9 小时前
C++技术岗面试经验总结
开发语言·网络·c++·网络协议·tcp/ip·面试
Wild_Pointer.9 小时前
高效工具实战指南:从零开始编写CMakeLists
c++