关于深拷贝与浅拷贝

举个例子来说吧

 

这是个浅拷贝的例子

 

#include <iostream>

#include <cstring>

 

using namespace std;

 

class TString

{

public:

    TString(char *ap = "china");

    TString(const TString &r);

    ~TString();

    void display()const;

private:

    char *m_pstr;

};

 

TString::TString(char *ap)

{

    if (ap)

    {

        m_pstr = new char[strlen(ap)+1];

        strcpy(m_pstr, ap);

    }

    else

        m_pstr = 0;

}

 

TString::TString(const TString &r)

{

    m_pstr = r.m_pstr;

} //人为实现默认拷贝构造函数

 

void TString::display()const

{

    cout << m_pstr << endl;

}

 

TString::~TString()

{

   delete []m_pstr;

}

 

int main()

{

    TString str1("japan");

    str1.display();

    TString str2;

    str2.display();

    TString str3(str2);

    str3.display();

 

    return 0;

}

 

 

这样程序在编译时无错误也无警告,但在执行后会出错 “Debug Assertion Failed”, 中断执行。因为在执行 TString str3(str2);语句时,系统调用默认拷贝构造函数,负责将对象str1的数据成员m_pstr中存放的地址赋值给str2中的m_pstr.如下图所示:

            

这样在执行display()的时候看不出问题,但是,当对象生命周期结束需要撤销对象时,首先由str3对象调用析构函数,将str3.m_pstr所指向的字符串china所在的动态内存空间释放,此时内存状态如图。这样在str2调用析构函数之前,m_pstr成了悬挂指针。因此str2无法正确执行析构函数代码delete []m_pstr,从而容易导致出错。

 

 

把上边的系统默认构造函数改一下,就变成了深拷贝。

 

//定义拷贝构造函数

 

TString::TString(const TString &r)

{

if (r.m_pstr)

{

m_pstr = new char[strlen(r.m_pstr)+1];

strcpy(m_pstr, r.m_pstr);

}

else

m_pstr = 0;

}

这样在执行 TString str3(str2)时,如右图所示这样就不会有悬挂指针的问题出现了。

 

这就是深拷贝。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值