首先应该考虑异常安全性
https://blog.youkuaiyun.com/bonchoix/article/details/8046727
一个函数如果说是“异常安全”的,必须同时满足以下两个条件:1.不泄漏任何资源;2.不允许破坏数据。 (内存泄漏:指程序在申请内存后,无法释放已申请的内存空间)
其次要满足四个点:
1.把返回值的类型声明为该类型的引用,并在函数结束前返回实例自身的引用(*this)。只有返回一个引用,才可以允许连续赋值(从右到左),否则无法通过编译。
2.把传入的参数声明为常量引用,假如是实例,从形参到实参会调用一次复制构造函数,声明为引用可以避免无谓消耗,提高代码的效率;同时在赋值运算符函数内不会改变传入的实例的状态,需要加上const关键字。
3.先判断是否自复制,假如在分配新内存之前释放自身已有的空间,则程序将出现内存泄漏。
4.假如不是自复制,先回收左操作数指针指向的原来的空间,再进行深拷贝。
Computer & operator=(const Computer & rhs)
{
cout << "Computer & operator=(const Computer & rhs)" << endl;
if(this != &rhs)//1.先判断是否是自复制
{
delete [] _brand;//2. 回收左操作数指针原来的空间
this->_brand = new char[strlen(rhs._brand)+1]();//3. 深拷贝
//+1是指字符串的\0,()是指将new空间初始化
strcpy(_brand, rhs._brand);
_price = rhs._price;
}
return *this;
}
剑指offer源码:
假如需要实现异常安全性,有两种方法。
一种是先用new分配新内容,再用delete释放已有的内容,也就是保证了分配内存失败时我们可以确保该类的实例不会被修改
另一种是先创建一个临时实例,再交换临时实例和原来的实例,代码如下:
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;
}
重点是对代码的异常安全性的理解
struct 和 class的区别是:如果没有标明成员函数或者成员变量的访问权限级别,那么在struct中默认的是public,而在class中默认的是private。