【C++基础之四】深拷贝和浅拷贝
2013-09-11 09:47
134 查看
1.普通类型对象的拷贝
普通类型对象的拷贝很简单,就是值的复制而已。比如:int _tmain(int argc, _TCHAR* argv[]) { int a=1; int b=a; return 0; }
2.类对象的拷贝
类对象的拷贝相比于普通类型的拷贝就复杂多了,它存在着各种成员变量。比如:CopyTest.h
class CCopyTest { public: CCopyTest(int _size):size(_size){} ~CCopyTest(void){} private: int size; };
main.cpp
int _tmain(int argc, _TCHAR* argv[]) { CCopyTest a(3),b=a; return 0; }
程序运行正常,b.size=3,看起来好像和普通类型数据也没什么差。好吧,继续往下看。
3.浅拷贝
我们再看一个例子。main.cpp和上面一样,CopyTest.h改为:
class CCopyTest { public: CCopyTest(int _size):size(_size){data=new int[size];} ~CCopyTest(void){delete []data;}//这里进行了资源的释放 private: int size; int* data; };
这时运行发现程序挂掉了,或者崩溃或者未响应。为什么呢?
原因:
这时候浅拷贝的概念出来了。在将一个对象赋值给另外一个对象的时候,如果只是进行数据成员间值的简单拷贝,比如上面这个例子,b.size=a.size; b.data=a.data。注意,data可是个指针啊,那么此时a.data和b.data所指向的是同一块内存空间。对象a在虚构的时候,a.data所指向的堆内存被释放,这时再轮到对象b进行虚构,b.data所指向的堆内存再次要求被释放,就会出现问题。
而例子2没有异常的原因是因为CopyTest这个类中没有指针等引用其他资源的对象,所以这时浅拷贝和深拷贝对它而言并没有区别。
4.深拷贝
深拷贝指的就是当拷贝对象中有对其他资源(如堆、文件、系统等)的引用时(引用可以是指针或引用)时,对象的另开辟一块新的资源,而不再对拷贝对象中有对其他资源的引用的指针或引用进行单纯的赋值,然后同步复拷贝开辟空间的值。我们把上面的例子改一改。
main.cpp不变,CopyTest.h更改为:
class CCopyTest { public: CCopyTest(int _size):size(_size){data=new int[size];} ~CCopyTest(void){delete []data;} CCopyTest(const CCopyTest& _copy):size(_copy.size){data=new int[size];memcpy(data,_copy.data,size);}//自定义拷贝构造函数 private: int size; int* data; };
这里还要注意一点,拷贝构造函数必须采用引用传参的方式,而不能采用值传参,因为值传参本身就要进行值拷贝,调用拷贝构造函数会引起无限循环嵌套,编译器会报错,栈溢出。VS和GCC中都会报错。
5.总结
总之,在对进行对象拷贝时,当对象包含对其他资源的引用,如果需要拷贝这个对象所引用的对象,那就是深拷贝,否则即是浅拷贝。相关文章推荐
- [C++基础]021_浅拷贝和深拷贝
- C++基础系列:深拷贝浅拷贝函数与拷贝赋值操作符
- c++基础:拷贝初始化和直接初始化的误区
- C++基础3 类:构造 拷贝 析构函数 静态变量函数 const初始化列表 new delete this 面向对象模型
- c++基础:拷贝初始化和直接初始化的误区
- C++基础——深拷贝&浅拷贝
- c++基础:拷贝初始化和直接初始化的误区
- c++基础:拷贝初始化和直接初始化的误区
- 【C++基础】——拷贝构造函数的浅拷贝和深拷贝
- 【基础】简析浅拷贝与深拷贝--C++源代码(VS2015)
- C++基础:四大基本函数,构造,析构,拷贝构造,赋值函数
- c++基础:拷贝初始化和直接初始化的误区
- c++基础学习之深拷贝
- c++基础:拷贝初始化和直接初始化的误区
- 【基础C&C++】内存拷贝strcpy,memcpy,memmove,strncpy源码
- c++基础概念之深浅拷贝
- C++基础之深拷贝浅拷贝
- c++基础:拷贝初始化和直接初始化的误区
- [C++基础]深拷贝和浅拷贝
- C++基础的不能再基础的学习笔记——拷贝控制(一)