C++ 系列:深拷贝与浅拷贝
Copyright © 1900-2016, NORYES, All Rights Reserved.
http://www.cnblogs.com/noryes/
欢迎转载,请保留此版权声明。
---------------------------------------------------------------------------------------
浅拷贝,即在定义一个类A,使用类似A obj; A obj1(obj);或者A obj1 = obj; 时候,由于没有自定义拷贝构造函数,C++编译器自动会产生一个默认的拷贝构造函数。这个默认的拷贝构造函数采用的是“位拷贝”(浅拷贝),而非“值拷贝”(深拷贝)的方式,如果类中含有指针变量,默认的拷贝构造函数必定出错。
用一句简单的话来说就是浅拷贝,只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
浅拷贝会出现什么问题呢?
假如有一个成员变量的指针,char *m_data;
其一,浅拷贝只是拷贝了指针,使得两个指针指向同一个地址,这样在对象块结束,调用函数析构的时,会造成同一份资源析构2次,即delete同一块内存2次,造成程序崩溃。
其二,浅拷贝使得obj.m_data和obj1.m_data指向同一块内存,任何一方的变动都会影响到另一方。
其三,在释放内存的时候,会造成obj1.m_data原有的内存没有被释放(这句话,刚开始我不太理解,如果没有走自定义的拷贝构造函数,申请内存空间,A obj1(obj);也不走默认构造函数,走的是默认的拷贝构造函数,何来分配空间直说,更不会造成obj1.m_data原有的内存没有被释放,这里刚开始我一直有疑问),造成内存泄露。
事实是这样的,当delete obj.m_data, obj.m_data内存被释放后,由于之前obj.m_data和obj1.m_data指向的是同一个内存空间,obj1.m_data所指的空间不能在被利用了,delete obj1.m_data也不会成功,一致已经无法操作该空间,所以导致内存泄露。
深拷贝采用了在堆内存中申请新的空间来存储数据,这样每个可以避免指针悬挂。
以 String 类为例,自定义了拷贝构造函数后不会发生内存泄露。
class String
{
public:
String(const char* str = NULL);
~String();
String(const String& rhs);
String& operator =(const String& rhs); private:
char* m_data;
};
String::String(const char* str)
{
if (NULL == str)
{
m_data = new char[1];
*m_data = '\0';
} m_data = new char[strlen(str) + 1];
strcpy(m_data, str);
} String::~String()
{
delete []m_data;
} String::String(const String& rhs)
{
m_data = new char[strlen(rhs.m_data) + 1];
strcpy(m_data, rhs.m_data);
} String& String::operator=(const String& rhs)
{
if (this == &rhs)
{
return *this;
} delete []m_data;
m_data = new char[strlen(rhs.m_data) + 1];
strcpy(m_data, rhs.m_data); return *this;
}
C++ 系列:深拷贝与浅拷贝的更多相关文章
- [C#进阶系列]专题一:深入解析深拷贝和浅拷贝
一.前言 这个星期参加了一个面试,面试中问到深浅拷贝的区别,然后我就简单了讲述了它们的之间的区别,然后面试官又继续问,如何实现一个深拷贝呢?当时只回答回答了一种方式,就是使用反射,然后面试官提示还可以 ...
- Java问题解读系列之IO相关---Java深拷贝和浅拷贝
前几天和棒棒童鞋讨论Java(TA学的是C++)的时候,他提到一个浅拷贝和深拷贝的问题,当时的我一脸懵圈,感觉自己学Java居然不知道这个知识点,于是今天研究了一番Java中的浅拷贝和深拷贝,下面来做 ...
- 死磕Java面试系列:深拷贝与浅拷贝的实现原理
深拷贝与浅拷贝的问题,也是面试中的常客.虽然大家都知道两者表现形式不同点在哪里,但是很少去深究其底层原理,也不知道怎么才能优雅的实现一个深拷贝.其实工作中也常常需要实现深拷贝,今天一灯就带大家一块深入 ...
- C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝
原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...
- Objective-C中的深拷贝和浅拷贝
在Objective-C中对象之间的拷贝分为浅拷贝和深拷贝.说白了,对非容器类的浅拷贝就是拷贝对象的地址,对象里面存的内容仍然是一份,没有新的内存被分配.对非容器类的深拷贝就是重写分配一块内存,然后把 ...
- $.extend()的深拷贝和浅拷贝详细讲解
版权声明:作者原创,转载请注明出处! 语法:jQuery.extend( [deep ], target, object1 [, objectN ] ) 描述: 将两个或更多对象的内容合并到第一个对象 ...
- JavaScript中面向对象的的深拷贝和浅拷贝
理解深拷贝和浅拷贝之前需要弄懂一些基础概念,内存中存储的变量类型分为值类型和引用类型. 1.值类型赋值的存储特点, 将变量内的数据全部拷贝一份, 存储给新的变量. 例如:var num = 123 : ...
- C++深拷贝与浅拷贝
当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用.也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用.以下情况都会调用拷贝构造函数: (1)一个对 ...
- C++的深拷贝与浅拷贝
对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面是一个类对象拷贝的简单例子. #i ...
- Python赋值语句与深拷贝、浅拷贝的区别
参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...
随机推荐
- 测试开发面试-java持续累积
接口和抽象类的区别 对java线程的理解 对java并发的理解 webservice的特点,用webservice的原因 守护线程和非守护线程 单例的实现,单例并发 如何实现定义一个类,只实现接口的任 ...
- 一个用纯CSS实现的下拉菜单
用CSS做下拉列表的特效,代码如下: <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> & ...
- vue自定义指令
Vue自定义指令: Vue.directive('myDr', function (el, binding) { el.onclick =function(){ binding.value(); } ...
- .htaccess语法之RewriteCond与RewriteRule指令格式详细解释
htaccess语法之RewriteCond与RewriteRule指令格式详细解释 (2012-11-09 18:09:08) 转载▼ 标签: htaccess it 分类: 网络 上文htacc ...
- Javascript操作DOM常用API总结
基本概念 在讲解操作DOM的api之前,首先我们来复习一下一些基本概念,这些概念是掌握api的关键,必须理解它们. Node类型 DOM1级定义了一个Node接口,该接口由DOM中所有节点类型实现.这 ...
- XSS(跨站脚本攻击)的最全总结
从OWASP的官网意译过来,加上自己的理解,算是比较全面的介绍.有兴趣的可私下交流. XSS 跨站脚本攻击 ============================================== ...
- Linux平台开发指南
声明:以下内容摘自http://www.me115.com/post/25.html 以下技术和工具是Linux平台下工作的基础,熟练掌握: C++ 工作语言,重要性不言而喻: 入门: <C++ ...
- 【荐】如何规划 Nginx 网站目录的权限(用户,用户组,ssh,sftp)
从上一篇文章:PHP网站(nginx.php-fpm.mysql) 用户权限解析,可以学习了解到,nginx 和 php-fpm 的用户是如何运作的. 有个工作场景: 1.公司的一台 CentOS 服 ...
- php数组array_push()和array_pop()以及array_shift()函数
<?php /** * array_push()将一个或多个单元压入数组的末尾(入栈) */ $stack = array("Java", "Php", ...
- mysql存储过程编写-入门案例-遁地龙卷风
(-1)写在前面 这篇文章只是简要的叙述了mysql存储过程编写的基本概念. 我使用的mysql版本是5.7.9-log. 参照<<深入浅出MySQL>>. (0) delim ...