C++笔记 | C++ 面试题:给类重载赋值操作符

比如以下是CMyString的声明,请为该类添加赋值操作符

Class CMyString

{

Public:

CMyString(char *pDatra = nullptr);

CMyString(constCMyString &str);

~CMyString(void);

Private:

Char * m_pData;

};

为这个函数重载一个赋值操作符

在为这个类重载赋值操作符的时候首先需要注意一下几点:

1)       返回值的类型得是该类的引用,并在函数结束前返回实例自身的引用(*this),只有这样连续赋值才可以通过,比如有三个CMyString对象,str1,str2,str3,str1=str2=str3必须返回引用才可以通过,至于为何要返回自身的引用是因为,假如返回对象,会再次调用一次拷贝构造函数,这就造成了多于的时间

2)       要把传入的参数设置为常量的引用,如果传入的参数不是引用而是实例,那么传入的参数又会调用一次拷贝构造函数,把参数声明为引用可以避免这样的无谓的消耗,同时传入的参数应该是不能修改,所以改为const

3)       实例自身有一个Char *指针,在使用新的实例给他赋值的时候需要把它释放掉,要不然会出现内存泄露

4)       这一点可能很难想到,需要判断传入的的实例是不是其本身,因为假如传入的实例是其本身的话,将char *释放掉之后在用其赋值会导致乱码,程序奔溃,

如何判断某个实例是否是其本身呢,这样判断是不对的,if(str==*this),这样是判断两个实例是否相等,不能判断两个实例是否是一个实例,而应该if(&str==this)用地址来判断才对

经典的写法,适用于初级程序员:

CMyString&CMyString::operator = (const CMyString &str)

{

If(this==&str)return *this;

Delete []m_pData;

m_pData =nullptr;

m_pData = newchar[strlen(str.m_pData)+1];

strcpy(m_pData,str.m_pData);

return *this;

}

在这个写法中,使用delete释放了指针的空间,如果申请新的空间,如果此时内存不足导致new char抛出异常,则m_pData将是一个空指针,这样非常容易导致程序崩溃,这就违背了异常安全性的原则,当抛出异常的时候应该保证数据不被修改,程序不会崩溃、

要想在赋值运算中实现异常安全性,我们有两种方法,一种简单的方法是我们先用new分配新的内存,再用delete释放已有的内容

第二种方法即先创建一个临时实例,在交换临时实例和原来的实例,下面是这种思路的参考代码

CMyString&CMyString :: operator = (const CMyString &str)

{

If(this!=&str)

{

CMyStringstrTemp(str);

Char * pTemp =strTemp.m_pData;

strTemp.m_pData= m_pData;

m_PData = pTemp;

}

Return *this;

}

如果pTemp声明成功, 会交换this和pTemp的内容,然后会调用pTemp的析构函数把原来的内容释放掉,

如果声明失败,原来的类的实例不会发生改变,这样就维护了异常安全性

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值