C++法则3:使用拷贝和交换的赋值运算符自动就是异常安全的,且能正确处理自赋值。
这条法则强调了使用"拷贝和交换"(Copy-and-Swap)惯用法来实现赋值运算符(=)的优点:
关键点
-
异常安全:拷贝和交换方法天然提供了强异常安全保证,因为在修改左侧对象之前,所有操作都已完成。
-
自赋值安全:这种方法自动正确处理自赋值情况(如
x = x
),不需要显式检查。 -
代码复用:它利用了拷贝构造函数和swap函数的已有实现,避免了代码重复。
典型实现
(1)
//注意rhs是按值传递的,意味着HasPtr持拷贝构造函数//将右侧运算符对象中的string拷贝到rhsHasPtr& HasPtr::operator=(HasPtr rhs){//交换左侧运算对象和局部变量rhs的内容swap(*this,rhs); //rhs现在是指向本对象曾经使用的内存return *this; //rhs被销毁,从而delete了rhs中的指针}
(2)
class MyClass {
public:// 拷贝赋值运算符MyClass& operator=(MyClass other) { // 注意:参数是按值传递swap(*this, other);return *this;}// 交换函数friend void swap(MyClass& first, MyClass& second) noexcept {using std::swap;// 交换所有成员swap(first.data, second.data);// ... 其他成员的交换}
};
工作原理
-
参数是按值传递的,这会调用拷贝构造函数创建临时副本
-
然后与当前对象交换内容
-
临时对象在函数结束时销毁,带走原内容
优势
-
简洁且不易出错
-
自动获得异常安全性
-
正确处理自赋值
-
与移动语义自然配合(C++11及以上)
这种方法遵循了DRY(Don't Repeat Yourself)原则,减少了代码重复和潜在错误。