[c++]深拷贝及浅拷贝问题案例详解

浅拷贝

我们先创建一个Computer类,头文件Computer.h 代码如下

class Computer
{
private:
    char *_brand;
    float _price;
public:
    void setBrand(const char* brand){
        strcpy(_brand,brand);
    }
    void setPrice(float price){
        _price=price;
    }

    void print(){
        cout<<" brand :"<<_brand<<endl
        <<" price :"<<_price<<endl;
    }
    
Computer(const char* brand,float price);
Computer(const char* brand);
Computer(const Computer& rhs);
~Computer();
};

我们可以看到其成员变量有一个字符指针 _brand,在创建对象的过程中指向堆空间的内容,Computer.cc文件包含其构造函数,析构函数

//析构函数
Computer::~Computer(){
    cout<<"~Computer"<<endl;
    /* if(_brand != nullptr) */
    if(_brand)
    {
        /* cout << "delete [] _brand" << endl; */
        delete [] _brand;
        _brand = nullptr;
    }
}

//构造函数
Computer::Computer(const char* brand,float price)
:_brand(new char[strlen(brand)+1]())
,_price(price)
{
   strcpy(_brand,brand);
    _price=price;
}
//构造函数
Computer::Computer(const char* brand)
//初始化列表
:_price(0)
{
 strcpy(_brand,brand);   
}

在测试过程(代码如下main.cc)中我们可以看到com1对象申请一块堆空间为“华硕”,我们又创建了一个对象com2与com1相等,此时com2的字符指针指向的和com1指向的是同一块堆空间的内容,所以在修改为“MAC”后打印出的com1和com2商标都为“MAC”。同时又因为在析构时com1释放了堆空间的内容,在析构com2时出现了报错。

void test(){
    Computer com1("华硕",1000);
    Computer com2=com1;
    cout<<"com1"<<&com1<<endl;
    cout<<"com2"<<&com2<<endl;
    com2.setBrand("MAC");
    com1.print();
    com2.print();
   

}



int main(){
    test();
    return 0;
}
/*运行结果如下
Cp10x7fffffffde80
Cp30x7fffffffde90
 brand :MAC
 price :1000
 brand :MAC
 price :1000
~Computer
~Computer
free(): double free detected in tcache 2

*/

深拷贝

那么怎么样避免这种情况?去完全的拷贝对象的所有内容,这就是深拷贝。我们可以将默认拷贝构造函数进行修改如下,我们在拷贝的时候同时在堆空间中申请了一份空间,示例图如下

//浅拷贝如下示范
Computer::Computer(const Computer& rhs)
// :_brand(new char[strlen(rhs._brand)+1]())
:_brand(rhs._brand)
,_price(rhs._price)
{
    // strcpy(_brand,rhs._brand);
}

//深拷贝如下
Computer::Computer(const Computer& rhs)
:_brand(new char[strlen(rhs._brand)+1]())
// :_brand(rhs._brand)
,_price(rhs._price)
{
    strcpy(_brand,rhs._brand);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunshinnnny

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值