文档目录

一、异常安全的赋值运算符

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,否则退回到拷贝构造。