一、异常安全的赋值运算符
class Buffer {
int* data_;
size_t size_;
public:
// 拷贝构造
Buffer(const Buffer& other) : size_(other.size_) {
data_ = new int[size_];
std::copy(other.data_, other.data_ + size_, data_);
}
// 析构
~Buffer() { delete[] data_; }
// 赋值运算符——Copy-and-Swap 写法
Buffer& operator=(Buffer other) { // 传值:拷贝构造或移动构造
swap(other);
return *this;
}
// 交换
void swap(Buffer& other) noexcept {
std::swap(data_, other.data_);
std::swap(size_, other.size_);
}
};
为什么这种写法是异常安全的?
传统写法:
Buffer& operator=(const Buffer& other) {
delete[] data_; // 先释放旧资源
data_ = new int[other.size_]; // 如果这里 new 抛异常 → data_ 悬垂!💥
size_ = other.size_;
std::copy(...);
return *this;
}
Copy-and-Swap:先拷贝(可能抛异常,但原对象不受影响),如果拷贝成功,再交换指针。即使拷贝抛出异常,原对象不变。
swap 要标记 noexcept:因为 std::vector 等容器在扩容时,会优先使用 noexcept 的移动构造/swap,否则退回到拷贝构造。