赋值运算符重载

在下面类中实现:

class CMyString
{
public:
    CMyString(char* pData = NULL);
    CMyString(const CMyString& str);
    CMyString& operator=(const CMyString& str);
    ~CMyString(void);
private:
    char * m_pData;
};

为了写出一个完整的赋值运算符重载函数,我们要考虑以下几个问题

  • 是否把返回值的类型声明为该类类型的引用,并在函数结束之前返回自身的引用(*this)。只有返回一个引用,才可以连续赋值,同时在赋值过程中不会改变传入实例的状态,加上const关键字
  • 是否释放实例自身已有的内存。如果我们忘记在分配新内存之前释放自身已有的内存,程序会出现内存泄漏
  • 是否判断传入的参数和当前实例是不是同一个实例。如果事先不判断就进行赋值,那么在释放自身的内存中将会导致严重的问题,当*this和传入的参数是同一个实例时,那么一旦释放自身的内存,传入参数的内存也将会被释放,找不到需要赋值的内容了

一步步解决上述的问题,我们可以编写出经典的算法

CMyString& CMyString::operator=(const CMyString& str)
{
    if(this != &str)
    {
        delete[] this->m_pData;
        this->m_pData = NULL;
        this->m_pData = new char[strlen(str.m_pData)+1];
        strcpy(this->m_pData,str);
    }
    return *this;
}

考虑到异常安全性的解法
在前面的函数中,我们在分配内存之前就先释放掉了实例的m_pData的内存。如果此时内存不足导致new char异常,m_pData将会是一个空指针,这样程序容易崩溃。
解决办法:创建一个临时实例,再交换临时实例和原来的实例

CMyString& CMyString::operator=(const CMyString& str)
{
    if(this != &str)
    {
        CMyString strTemp(str);
        char* pTemp = strTemp.m_pData ;
        strTemp.m_pData = m_pData;
        m_pData = pTemp;    
    }
    return *this;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值