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. Net中对Object的定义

    如果你问一个.Net程序员什么是Object,他可能会信誓旦旦的告诉你"Object还不简单吗,就是所有类型的基类"这个答案是对的,但是不足以说明Object真正是什么 好在HTM ...

  2. nodejs URL解析

    说到URL就需要提一下URI,一个网址就是一个URL,是一个具体的符号,说明了要通过什么协议来访问某种资源,URI是一个字符格式规范,URL是URI的一个子集,URL肯定是URI,但URI却不一定是U ...

  3. JAVA中ListIterator和Iterator详解与辨析

    在使用Java集 合的时候,都需要使用Iterator.但是java集合中还有一个迭代器ListIterator,在使用List.ArrayList. LinkedList和Vector的时候可以使用 ...

  4. Canvas绘制时钟

    ①首先在HTML的body标签中添加一个canvas标签,用于绘制时钟. <canvas id="myCanvas" width="600" height ...

  5. Fedora20-32bit cross-compiling arm-linux-gcc4.3.2

    目录 0 前言 1 安装arm-linux-gcc-4.3.2 2 配置 nfs 服务器 0 前言 之前在 fedora 64bit 上建立交叉编译,但由于4.4.3版本需要另装用于gdb-serve ...

  6. 五大主流浏览器 CSS3 和 HTML5 兼容性大比拼

    各大主流浏览器对 CSS3 和 HTML5 的支持越来越完善,曾经让多少前端开发人员心碎的IE系也开始拥抱标准.就在前几天,W3C的 HTML5 社区领袖 Shelley 宣布,HTML5的开发工作已 ...

  7. Linux 下安装JRuby

    安装ruby cd git clone https://github.com/rbenv/rbenv.git ~/.rbenv echo 'export PATH="$HOME/.rbenv ...

  8. webpack 配置文件

    现如今,webpack非常的受欢迎,比较火的几款js框架都推荐使用webpack来构建项目,而webpack也确实非常强大,但是配置webpack缺常常带来很多问题,接下来就写一下我自己遇到的一些坑. ...

  9. webstorm ES6 转 ES5

    一句话总结:用WebStorm自带的File Watcher功能+Babel实现自动转换ECMAScript 6代码为ES5代码 1. 新建一个Empty Project,然后在src目录下新建了一个 ...

  10. Archlinux安装MySQL5.7.14压缩包版

    现在Arch官方源里是MariaDB,MySQL扔到AUR里去了...感觉还是自己安装好些... (参考资料:度娘.官方文档) 贴配置: lts版的 在Vbox虚拟机测试 按照官方文档的安装步骤: 创 ...