0 题目
为了一个类添加一个赋值运算符函数
class Str { public: Str(char *p=nullptr); Str(const Str& str); ~str(); private: char* m_data; }
1 分析
赋值运算符,也就是重载=号运算符。重载赋值运算符需要注意:
- 返回自身引用,因此可以实现连=操作
- 传入参数为引用,减少开销
- 如果类内对象,由在堆上分配内存。或者说是类的析构函数会释放某些数据成员,那么该数据成员就需要深度拷贝
- 传入自身的时候,需要判断是否需要赋值
- 在赋值发生错误的时候,能够回滚到原来的状态。
2 方案
Str &Str::operator=(/*const*/ Str &str) { if (this != str) { Str tmp(str); // 使用已有的拷贝拷贝构造函数,拷贝构造函数默认已经是深拷贝 swap(tmp); // 离开作用域的时候,tmp带着this原来的m_data被 Str的析构函数析构了 } return this; } void Str::swap(Str &str) { char *tmp = str.m_data; str.m_data = m_data; m_data = tmp; // 如果有其他需要交换的,那么在后面添加 } // 另一种实现,不在传入应用,直接在传值截断进行 拷贝, // 性能靠编译器来优化 Str &Str::operator=(Str str) { Str tmp(str); // 使用已有的拷贝拷贝构造函数,拷贝构造函数默认已经是深拷贝 swap(tmp); // 离开作用域的时候,tmp带着this原来的m_data被 Str的析构函数析构了 return this; }