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

时间:2021-01-20 19:47:02

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

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

图示:

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