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++ 系列:深拷贝与浅拷贝的更多相关文章

  1. [C#进阶系列]专题一:深入解析深拷贝和浅拷贝

    一.前言 这个星期参加了一个面试,面试中问到深浅拷贝的区别,然后我就简单了讲述了它们的之间的区别,然后面试官又继续问,如何实现一个深拷贝呢?当时只回答回答了一种方式,就是使用反射,然后面试官提示还可以 ...

  2. Java问题解读系列之IO相关---Java深拷贝和浅拷贝

    前几天和棒棒童鞋讨论Java(TA学的是C++)的时候,他提到一个浅拷贝和深拷贝的问题,当时的我一脸懵圈,感觉自己学Java居然不知道这个知识点,于是今天研究了一番Java中的浅拷贝和深拷贝,下面来做 ...

  3. 死磕Java面试系列:深拷贝与浅拷贝的实现原理

    深拷贝与浅拷贝的问题,也是面试中的常客.虽然大家都知道两者表现形式不同点在哪里,但是很少去深究其底层原理,也不知道怎么才能优雅的实现一个深拷贝.其实工作中也常常需要实现深拷贝,今天一灯就带大家一块深入 ...

  4. C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝

    原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...

  5. Objective-C中的深拷贝和浅拷贝

    在Objective-C中对象之间的拷贝分为浅拷贝和深拷贝.说白了,对非容器类的浅拷贝就是拷贝对象的地址,对象里面存的内容仍然是一份,没有新的内存被分配.对非容器类的深拷贝就是重写分配一块内存,然后把 ...

  6. $.extend()的深拷贝和浅拷贝详细讲解

    版权声明:作者原创,转载请注明出处! 语法:jQuery.extend( [deep ], target, object1 [, objectN ] ) 描述: 将两个或更多对象的内容合并到第一个对象 ...

  7. JavaScript中面向对象的的深拷贝和浅拷贝

    理解深拷贝和浅拷贝之前需要弄懂一些基础概念,内存中存储的变量类型分为值类型和引用类型. 1.值类型赋值的存储特点, 将变量内的数据全部拷贝一份, 存储给新的变量. 例如:var num = 123 : ...

  8. C++深拷贝与浅拷贝

    当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用.也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用.以下情况都会调用拷贝构造函数: (1)一个对 ...

  9. C++的深拷贝与浅拷贝

    对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面是一个类对象拷贝的简单例子. #i ...

  10. Python赋值语句与深拷贝、浅拷贝的区别

    参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...

随机推荐

  1. leggere la nostra recensione del primo e del secondo

    La terra di mezzo in trail running sembra essere distorto leggermente massima di recente, e gli aggi ...

  2. mysql复习相关

    Mysql相关 mysql增删改查 我们需要修改数据表名或者修改数据表字段时,就需要使用到Mysql Alter命令 删除,添加或修改表字段 alter table student drop regi ...

  3. express之sendFile

    module.exports = function(req, res, opt) { var applyNo = req.query.applyNo; console.log("applyN ...

  4. thinkphp3.22 多项目配置

    1.index.php if(version_compare(PHP_VERSION,'5.3.0','<')) die('require PHP > 5.3.0 !'); // 开启调试 ...

  5. swift3.0变化总结

    Swift 3.0 做出的改变很大,在这篇文章中,我将尽我所能,利用代码样例给大家解释Swift 3.0最重要(要命)的改变,希望大家能够做好升级Swift 3.0 的准备.Swift 3.0的改变不 ...

  6. 基于jQuery的Validate表单验证

    表单验证可以说在前端开发工作中是无处不在的~ 有数据,有登录,有表单, 都需要前端验证~~  而我工作中用到最多的就是基于基于jQuery的Validate表单验证~  就向下面这样~ 因为今天有个朋 ...

  7. AD域组策略-只显示指定的控制面板选项配置方法

    操作方法: 1.打开组策略管理器,新建一个组策略并右击编辑. 2,找到隐藏指定的“控制面板”项并双击打开:并参照设置: 填入要显示的控制面板项目,比如: joystick.cpl 表示将显示“游戏控制 ...

  8. JS中用apply、bind实现为函数或者类传入动态个数的参数

    为纪念10年没写blog,第一篇博文就以这样一个有趣的窍门开始吧 -___- 在ES5中,当我们调用一个函数时,如果要传入的参数是根据其他函数或条件判断生成的,也就是说不确定会传入多少个参数时,在不改 ...

  9. 11个审查Linux是否被入侵的方法

    11个审查Linux是否被入侵的方法 一.检查系统日志 lastb命令 检查系统错误登陆日志,统计IP重试次数 二.检查系统用户 1.cat /etc/passwd 查看是否有异常的系统用户 2.gr ...

  10. git clone出现的error: The requested URL returned error: 401 Unauthorized

    error: The requested URL returned error: 401 Unauthorized while accessing https://git.oschina.net/.. ...