C++对象的深拷贝和浅拷贝

深拷贝:当对象中含有指针域的时候,在进行对象之间初始化(也就是调用拷贝构造函数)或者是=操作的时候(注:浅两者是不同的情况),将指针所包含的内存空间中的内容也进行拷贝

浅拷贝:当对象中含有指针域的时候,在进行对象之间初始化(也就是调用拷贝构造函数)或者是=操作的时候(注:浅两者是不同的情况),单纯将指针的值(也就是所指内存空间的首地址)拷贝,这就导致两个对象的指针域是同一块内存,所以在对象生存周期完毕时,调用析构函数,释放内存的时候出现core down的情况!

原因分析:因为C++提供的默认拷贝构造函数和=操作都是浅拷贝操作,即只是将指针域进行值复制。

解决方法:重写默认拷贝构造函数 和 重载=操作符

#include "iostream"
using namespace std;

class Name
{
public:
    Name (char *_name)
    {
        this->size = strlen(_name)+1;
        this->pName = (char *)malloc(size);
        strcpy(this->pName, _name);
    }
    // 重写类的拷贝构造函数,使之完成深拷贝
    Name (Name &_name)
    {
        this->size = _name.size;
        this->pName = (char *)malloc(size+1);
        strcpy(this->pName, _name.pName);
    }
    ~Name ()
    {
        free(this->pName);
        this->size = 0;
        this->pName = NULL;
    }
    // 重写=操作符,使之完成深拷贝
    void operator= (Name &_name)
    {
        if(this->pName!=NULL)
        {
            free(this->pName);
            this->size = 0;
        }
        this->pName = (char *)malloc(_name.size+1);
        this->size = _name.size;
    }
protected:
private:
    char *pName;
    int size;
};
void RunCopy()
{
    //定义obj2并且用obj1初始化
    Name obj1("obj1");
    Name obj2 = obj1; //默认的拷贝构造函数,提供的只是浅拷贝

    Name obj3("obj3.....");
    obj2 = obj3;      //默认的等号操作,提供的只是浅拷贝
}
int main()
{
    RunCopy();
    return 0;
}

需要注意的点:
1. 深拷贝和浅拷贝发生发生在类成员中包含有指针域的时候。

2. =操作符和对象的初始化是两种不同的东西!!

// 定义obj2并且用obj1初始化
Name obj1("obj1");
Name obj2 = obj1; // 进行的是拷贝构造函数

// 把obj3复制给obj2,用等号操作
Name obj3("obj3.....");
obj2 = obj3;      // 进行的是等号操作

3. 特别注意:在进行等号操作重载的时,先将原来的内存空间释放,(内存泄漏)

/*.......................*/
// 释放对象原来的内存块
// 防止产生内存泄漏
if(this->pName!=NULL)
{
    free(this->pName);
    this->size = 0;
}
/*.......................*/

图示:

时间: 2024-10-13 22:14:36

C++对象的深拷贝和浅拷贝的相关文章

C#对象的深拷贝与浅拷贝

转载自:http://blog.163.com/hr_msn/blog/static/21549405120132250396584/ 深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响.举个例子,一个人名叫张三,后来用他克隆(假设法律允许)了另外一个人,叫李四,不管是张三缺胳膊少腿还是李四缺胳膊少腿都不会影响另外一个人.比较典型的就是Value(值)对象,如预定义类型Int32,Double,以及结构(struct),枚举(Enum)等. 考虑以下写法 in

PHP中对象的深拷贝与浅拷贝

先说一下深拷贝和浅拷贝通俗理解 深拷贝:赋值时值完全复制,完全的copy,对其中一个作出改变,不会影响另一个 浅拷贝:赋值时,引用赋值,相当于取了一个别名.对其中一个修改,会影响另一个 PHP中, = 赋值时,普通对象是深拷贝,但对对象来说,是浅拷贝.也就是说,对象的赋值是引用赋值.(对象作为参数传递时,也是引用传递,无论函数定义时参数前面是否有&符号) <?php //普通对象赋值,深拷贝,完全值复制 $m = 1; $n = $m; $n = 2; echo $m;//值复制,对新对象的

探究JS中对象的深拷贝和浅拷贝

深拷贝和浅拷贝的区别 在讲深拷贝和浅拷贝的区别之前,回想一下我们平时拷贝一个对象时是怎么操作的?是不是像这样? var testObj1 = {a: 1, b:2}, testObj2=testObj1; testObj1.a = 7; console.log(testObj1); //{a: 7, b:2} console.log(testObj2); //{a: 7, b:2} 发现问题了吗?当testObj1变化时,testObj2相应的属性跟着变化了.这就是属于浅拷贝了,而所谓的深拷贝就

对象的深拷贝和浅拷贝

const obj = { a: 'hello', b: { a: 'hello', b: 'world' }, c: ['good', 'good','study'], d: function() { console.log('hello world') } } 对象的浅拷贝 方法一:(for in循环) function simpleCopy (data) { let newObj = {}; if (data) { for (let i in data) { newObj[i] = dat

java中对象的深拷贝和浅拷贝

根据对象成员变量的拷贝程度(基本数据类型.引用类型),可将拷贝分为浅拷贝和深拷贝. 一.浅拷贝 package javaKeyTechnology; class PerSon{ private String name; private int age; PerSon(String name,int age){ this.name = name; this.age = age; } public void setName(String name){ //私有数据的更改器 this.name = n

JS中实现数组和对象的深拷贝和浅拷贝

数组的拷贝 > 数组的深拷贝,两层 var arr = [[1,2,3],[4,5,6],[7,8,9]]; var arr2 = []; 循环第一层数组 for(var i=0,len=arr.length;i<len;i++){ 循环第二层数组 for(var k=0,lens=arr[i].length;k<lens;k++){ 把每一个数组的内容添加到数组2中 arr2.push(arr[i][k]); } } console.log(arr2); //[1, 2, 3, 4,

Python对象拷贝——深拷贝与浅拷贝

对象赋值 浅拷贝 深拷贝 1. 对象赋值 对象的赋值实际上是对对象的引用.也就是说当把一个对象赋值给另一个对象时,只是拷贝了引用.如: >>> t1 = tuple('furzoom') >>> t2 = t1 >>> id(t1),id(t2) (139792198303936, 139792198303936) 上面t1和t2代表的是同一个对象. 2. 浅拷贝 除了上面将一个对象直接赋值给另一个对象外,还有两种常用的方法对对象进行拷贝:使用切片操作

javascript -- 对象(深拷贝、浅拷贝)

拷贝:顾名思义就是复制. 1.浅拷贝:把父对象的属性,全部拷贝到子对象 function extendCopy(p) { var c = { }; for (var i in p) { c[i] = p[i] }; return c; } 2. 深拷贝就是能实现真正意义上的数组和对象的拷贝.   function deepCopy(p, c) { var c = c || {}; for (var i in p) { if (typeof p[i] === "object") { c[

iOS开发——深拷贝与浅拷贝详解

深拷贝和浅拷贝这个问题在面试中常常被问到,而在实际开发中,只要稍有不慎,就会在这里出现问题.尤其对于初学者来说,我们有必要来好好研究下这个概念.我会以实际代码来演示,相关示例代码上传至 这里 . 首先通过一句话来解释:深拷贝就是内容拷贝,浅拷贝就是指针拷贝. 深拷贝就是拷贝出和原来仅仅是值一样,但是内存地址完全不一样的新的对象,创建后和原对象没有任何关系.浅拷贝就是拷贝指向原来对象的指针,使原对象的引用计数+1,可以理解为创建了一个指向原对象的新指针而已,并没有创建一个全新的对象. (1)非容器