一、赋值运算符基础

1.1 赋值运算符的基本形式

class AssignmentBasics {
private:
    int* data;
    size_t size;
    std::string name;
    
public:
    // 标准的拷贝赋值运算符
    AssignmentBasics& operator=(const AssignmentBasics& other) {
        std::cout << "Copy assignment operator called\n";
        
        // 1. 自赋值检查(重要!)
        if (this == &other) {
            return *this;
        }
        
        // 2. 释放当前对象的资源
        delete[] data;
        
        // 3. 分配新资源并复制
        size = other.size;
        name = other.name;
        data = new int[size];
        std::copy(other.data, other.data + size, data);
        
        // 4. 返回*this的引用(支持链式赋值)
        return *this;
    }
    
    // 构造函数
    AssignmentBasics(size_t s = 0, const std::string& n = "default")
        : size(s), name(n), data(s ? new int[s]() : nullptr) {
        std::cout << "Constructor called for " << name << "\n";
    }
    
    // 拷贝构造函数(必须配合实现)
    AssignmentBasics(const AssignmentBasics& other)
        : size(other.size), name(other.name + "_copy") {
        data = new int[size];
        std::copy(other.data, other.data + size, data);
        std::cout << "Copy constructor called\n";
    }
    
    // 析构函数
    ~AssignmentBasics() {
        delete[] data;
        std::cout << "Destructor called for " << name << "\n";
    }
    
    // 辅助函数
    void print() const {
        std::cout << name << ": [";
        for (size_t i = 0; i < size; ++i) {
            std::cout << data[i] << (i < size-1 ? ", " : "");
        }
        std::cout << "]\n";
    }
};
 
// 使用示例
void demonstrateBasics() {
    AssignmentBasics obj1(5, "obj1");
    AssignmentBasics obj2(3, "obj2");
    AssignmentBasics obj3(4, "obj3");
    
    // 简单赋值
    obj2 = obj1;
    
    // 链式赋值
    obj3 = obj2 = obj1;
    
    // 自赋值
    obj1 = obj1;  // 应该安全处理
}

1.2 赋值运算符的特性

class AssignmentProperties {
public:
    int value;
    
    // 赋值运算符必须是成员函数
    AssignmentProperties& operator=(const AssignmentProperties& other) {
        value = other.value;
        return *this;
    }
    
    // 错误:不能定义为非成员函数
    // friend AssignmentProperties& operator=(AssignmentProperties& lhs, 
    //                                       const AssignmentProperties& rhs);
    
    // 赋值运算符不能被继承
    // 每个类都有自己的赋值运算符
    
    // 如果不提供,编译器会生成默认的赋值运算符
    // 默认赋值运算符执行成员逐一赋值
};
 
// 编译器生成的默认赋值运算符
class DefaultAssignment {
    int a;
    double b;
    std::string c;
    // 编译器生成的赋值运算符等价于:
    // DefaultAssignment& operator=(const DefaultAssignment& other) {
    //     a = other.a;
    //     b = other.b;
    //     c = other.c;
    //     return *this;
    // }
};

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

2.1 Copy-and-Swap惯用法

class CopyAndSwap {
private:
    int* data;
    size_t size;
    
public:
    // 构造函数
    explicit CopyAndSwap(size_t s = 0)
        : size(s), data(s ? new int[s]() : nullptr) {}
    
    // 拷贝构造函数
    CopyAndSwap(const CopyAndSwap& other)
        : size(other.size), data(other.size ? new int[other.size] : nullptr) {
        if (data) {
            std::copy(other.data, other.data + size, data);
        }
    }
    
    // 移动构造函数
    CopyAndSwap(CopyAndSwap&& other) noexcept
        : size(std::exchange(other.size, 0))
        , data(std::exchange(other.data, nullptr)) {}
    
    // 析构函数
    ~CopyAndSwap() {
        delete[] data;
    }
    
    // swap函数(不抛出异常)
    void swap(CopyAndSwap& other) noexcept {
        using std::swap;
        swap(size, other.size);
        swap(data, other.data);
    }
    
    // 方法1:统一的赋值运算符(按值传递)
    CopyAndSwap& operator=(CopyAndSwap other) {  // 注意:按值传递
        swap(other);
        return *this;
    }
    
    /* 方法2:分别实现拷贝和移动赋值
    // 拷贝赋值运算符
    CopyAndSwap& operator=(const CopyAndSwap& other) {
        CopyAndSwap temp(other);  // 拷贝构造临时对象
        swap(temp);               // 交换内容
        return *this;            // temp析构时清理旧资源
    }
    
    // 移动赋值运算符
    CopyAndSwap& operator=(CopyAndSwap&& other) noexcept {
        CopyAndSwap temp(std::move(other));  // 移动构造临时对象
        swap(temp);
        return *this;
    }
    */
};
 
// 为类定义专门的swap函数
inline void swap(CopyAndSwap& a, CopyAndSwap& b) noexcept {
    a.swap(b);
}

2.2 强异常保证的实现

class StrongExceptionSafety {
private:
    int* data;
    size_t size;
    size_t capacity;
    std::string metadata;
    
public:
    StrongExceptionSafety& operator=(const StrongExceptionSafety& other) {
        // 强异常保证:要么完全成功,要么状态不变
        
        if (this != &other) {
            // 1. 先分配新资源(可能抛出异常)
            int* newData = nullptr;
            if (other.size > 0) {
                newData = new int[other.capacity];  // 可能抛出bad_alloc
                
                // 2. 复制数据(使用不抛出异常的操作)
                std::copy(other.data, other.data + other.size, newData);
            }
            
            // 3. 所有可能抛出异常的操作完成后,执行不抛出异常的操作
            delete[] data;  // noexcept
            
            // 4. 更新成员(不抛出异常)
            data = newData;
            size = other.size;
            capacity = other.capacity;
            metadata = other.metadata;  // string的赋值提供强异常保证
        }
        
        return *this;
    }
    
    // 使用临时变量的另一种实现
    StrongExceptionSafety& operator=(const StrongExceptionSafety& other) {
        if (this != &other) {
            // 创建临时变量(可能抛出异常)
            StrongExceptionSafety temp(other);
            
            // 使用noexcept操作交换
            using std::swap;
            swap(data, temp.data);
            swap(size, temp.size);
            swap(capacity, temp.capacity);
            swap(metadata, temp.metadata);
            
            // temp析构时清理旧资源
        }
        return *this;
    }
};

三、移动赋值运算符

3.1 移动赋值运算符的实现

class MoveAssignment {
private:
    int* data;
    size_t size;
    std::vector<std::string> strings;
    std::unique_ptr<double[]> uniqueData;
    
public:
    // 移动赋值运算符(应该声明为noexcept)
    MoveAssignment& operator=(MoveAssignment&& other) noexcept {
        std::cout << "Move assignment operator called\n";
        
        // 1. 自移动检查
        if (this == &other) {
            return *this;
        }
        
        // 2. 释放当前资源
        delete[] data;
        
        // 3. 窃取资源(移动)
        data = std::exchange(other.data, nullptr);
        size = std::exchange(other.size, 0);
        strings = std::move(other.strings);
        uniqueData = std::move(other.uniqueData);
        
        // 4. other现在处于有效但未指定的状态
        
        return *this;
    }
    
    // 构造函数
    MoveAssignment(size_t s = 0) 
        : size(s)
        , data(s ? new int[s]() : nullptr)
        , uniqueData(std::make_unique<double[]>(s)) {}
    
    // 移动构造函数
    MoveAssignment(MoveAssignment&& other) noexcept
        : data(std::exchange(other.data, nullptr))
        , size(std::exchange(other.size, 0))
        , strings(std::move(other.strings))
        , uniqueData(std::move(other.uniqueData)) {}
    
    // 析构函数
    ~MoveAssignment() {
        delete[] data;
    }
};
 
// 测试移动赋值
void testMoveAssignment() {
    MoveAssignment obj1(100);
    MoveAssignment obj2(200);
    
    // 移动赋值
    obj2 = std::move(obj1);  // obj1变为移后状态
    
    // 从临时对象移动赋值
    obj2 = MoveAssignment(300);
    
    // 链式移动赋值
    MoveAssignment obj3(400);
    obj3 = std::move(obj2 = std::move(obj1));
}

3.2 完美的五法则实现

class RuleOfFive {
private:
    char* buffer;
    size_t length;
    mutable size_t useCount;  // 用于跟踪
    
    void log(const std::string& msg) const {
        std::cout << msg << " [length=" << length << "]\n";
    }
    
public:
    // 1. 普通构造函数
    explicit RuleOfFive(const std::string& str = "") 
        : length(str.length())
        , buffer(length ? new char[length + 1] : nullptr)
        , useCount(0) {
        if (buffer) {
            std::copy(str.begin(), str.end(), buffer);
            buffer[length] = '\0';
        }
        log("Constructor");
    }
    
    // 2. 析构函数
    ~RuleOfFive() {
        delete[] buffer;
        log("Destructor");
    }
    
    // 3. 拷贝构造函数
    RuleOfFive(const RuleOfFive& other)
        : length(other.length)
        , buffer(other.length ? new char[other.length + 1] : nullptr)
        , useCount(0) {
        if (buffer) {
            std::copy(other.buffer, other.buffer + length + 1, buffer);
        }
        log("Copy constructor");
    }
    
    // 4. 拷贝赋值运算符
    RuleOfFive& operator=(const RuleOfFive& other) {
        log("Copy assignment");
        
        if (this != &other) {
            // 使用copy-and-swap
            RuleOfFive temp(other);
            swap(temp);
        }
        return *this;
    }
    
    // 5. 移动构造函数
    RuleOfFive(RuleOfFive&& other) noexcept
        : buffer(std::exchange(other.buffer, nullptr))
        , length(std::exchange(other.length, 0))
        , useCount(std::exchange(other.useCount, 0)) {
        log("Move constructor");
    }
    
    // 6. 移动赋值运算符
    RuleOfFive& operator=(RuleOfFive&& other) noexcept {
        log("Move assignment");
        
        if (this != &other) {
            delete[] buffer;
            
            buffer = std::exchange(other.buffer, nullptr);
            length = std::exchange(other.length, 0);
            useCount = std::exchange(other.useCount, 0);
        }
        return *this;
    }
    
    // swap辅助函数
    void swap(RuleOfFive& other) noexcept {
        using std::swap;
        swap(buffer, other.buffer);
        swap(length, other.length);
        swap(useCount, other.useCount);
    }
    
    // 获取C字符串
    const char* c_str() const {
        ++useCount;
        return buffer ? buffer : "";
    }
    
    // 获取使用次数
    size_t getUseCount() const { return useCount; }
};

四、特殊类型的赋值运算符

4.1 不同类型的赋值

class FlexibleAssignment {
private:
    std::variant<int, double, std::string> data;
    
public:
    // 从int赋值
    FlexibleAssignment& operator=(int value) {
        data = value;
        return *this;
    }
    
    // 从double赋值
    FlexibleAssignment& operator=(double value) {
        data = value;
        return *this;
    }
    
    // 从string赋值
    FlexibleAssignment& operator=(const std::string& value) {
        data = value;
        return *this;
    }
    
    // 从const char*赋值
    FlexibleAssignment& operator=(const char* value) {
        data = std::string(value);
        return *this;
    }
    
    // 模板赋值运算符
    template<typename T>
    FlexibleAssignment& operator=(const std::vector<T>& vec) {
        std::stringstream ss;
        ss << "[";
        for (size_t i = 0; i < vec.size(); ++i) {
            ss << vec[i];
            if (i < vec.size() - 1) ss << ", ";
        }
        ss << "]";
        data = ss.str();
        return *this;
    }
    
    // 访问数据
    void print() const {
        std::visit([](const auto& value) {
            std::cout << value << "\n";
        }, data);
    }
};
 
// 使用示例
void testFlexibleAssignment() {
    FlexibleAssignment fa;
    
    fa = 42;                    // int赋值
    fa = 3.14;                  // double赋值
    fa = "Hello";               // const char*赋值
    fa = std::string("World");  // string赋值
    fa = std::vector<int>{1, 2, 3};  // vector赋值
}

4.2 复合赋值运算符

class CompoundAssignment {
private:
    double value;
    
public:
    CompoundAssignment(double v = 0.0) : value(v) {}
    
    // 算术复合赋值
    CompoundAssignment& operator+=(const CompoundAssignment& rhs) {
        value += rhs.value;
        return *this;
    }
    
    CompoundAssignment& operator-=(const CompoundAssignment& rhs) {
        value -= rhs.value;
        return *this;
    }
    
    CompoundAssignment& operator*=(const CompoundAssignment& rhs) {
        value *= rhs.value;
        return *this;
    }
    
    CompoundAssignment& operator/=(const CompoundAssignment& rhs) {
        if (rhs.value != 0) {
            value /= rhs.value;
        } else {
            throw std::domain_error("Division by zero");
        }
        return *this;
    }
    
    // 支持与标量的复合赋值
    CompoundAssignment& operator+=(double scalar) {
        value += scalar;
        return *this;
    }
    
    CompoundAssignment& operator*=(double scalar) {
        value *= scalar;
        return *this;
    }
    
    double getValue() const { return value; }
};
 
// 基于复合赋值实现算术运算符
CompoundAssignment operator+(CompoundAssignment lhs, 
                            const CompoundAssignment& rhs) {
    return lhs += rhs;  // 利用复合赋值
}
 
CompoundAssignment operator*(CompoundAssignment lhs, double scalar) {
    return lhs *= scalar;
}

4.3 位运算复合赋值

class BitOperations {
private:
    unsigned int bits;
    
public:
    BitOperations(unsigned int b = 0) : bits(b) {}
    
    // 位运算复合赋值
    BitOperations& operator&=(const BitOperations& rhs) {
        bits &= rhs.bits;
        return *this;
    }
    
    BitOperations& operator|=(const BitOperations& rhs) {
        bits |= rhs.bits;
        return *this;
    }
    
    BitOperations& operator^=(const BitOperations& rhs) {
        bits ^= rhs.bits;
        return *this;
    }
    
    BitOperations& operator<<=(unsigned int shift) {
        bits <<= shift;
        return *this;
    }
    
    BitOperations& operator>>=(unsigned int shift) {
        bits >>= shift;
        return *this;
    }
    
    // 设置特定位
    BitOperations& setBit(unsigned int pos) {
        if (pos < 32) {
            bits |= (1u << pos);
        }
        return *this;
    }
    
    // 清除特定位
    BitOperations& clearBit(unsigned int pos) {
        if (pos < 32) {
            bits &= ~(1u << pos);
        }
        return *this;
    }
    
    // 切换特定位
    BitOperations& toggleBit(unsigned int pos) {
        if (pos < 32) {
            bits ^= (1u << pos);
        }
        return *this;
    }
    
    bool testBit(unsigned int pos) const {
        return (pos < 32) && (bits & (1u << pos));
    }
    
    void print() const {
        std::cout << "Bits: " << std::bitset<32>(bits) << " (" << bits << ")\n";
    }
};

五、赋值运算符与继承

5.1 基类和派生类的赋值运算符

class Base {
protected:
    int* baseData;
    size_t baseSize;
    
public:
    Base(size_t size = 0) 
        : baseSize(size), baseData(size ? new int[size]() : nullptr) {
        std::cout << "Base constructor\n";
    }
    
    virtual ~Base() {
        delete[] baseData;
        std::cout << "Base destructor\n";
    }
    
    // 基类拷贝赋值运算符
    Base& operator=(const Base& other) {
        std::cout << "Base copy assignment\n";
        if (this != &other) {
            delete[] baseData;
            
            baseSize = other.baseSize;
            baseData = baseSize ? new int[baseSize] : nullptr;
            if (baseData) {
                std::copy(other.baseData, other.baseData + baseSize, baseData);
            }
        }
        return *this;
    }
    
    // 基类移动赋值运算符
    Base& operator=(Base&& other) noexcept {
        std::cout << "Base move assignment\n";
        if (this != &other) {
            delete[] baseData;
            
            baseData = std::exchange(other.baseData, nullptr);
            baseSize = std::exchange(other.baseSize, 0);
        }
        return *this;
    }
    
    virtual void print() const {
        std::cout << "Base: size=" << baseSize << "\n";
    }
};
 
class Derived : public Base {
private:
    double* derivedData;
    size_t derivedSize;
    
public:
    Derived(size_t bSize = 0, size_t dSize = 0)
        : Base(bSize)
        , derivedSize(dSize)
        , derivedData(dSize ? new double[dSize]() : nullptr) {
        std::cout << "Derived constructor\n";
    }
    
    ~Derived() override {
        delete[] derivedData;
        std::cout << "Derived destructor\n";
    }
    
    // 派生类拷贝赋值运算符
    Derived& operator=(const Derived& other) {
        std::cout << "Derived copy assignment\n";
        if (this != &other) {
            // 调用基类赋值运算符
            Base::operator=(other);
            
            // 处理派生类成员
            delete[] derivedData;
            
            derivedSize = other.derivedSize;
            derivedData = derivedSize ? new double[derivedSize] : nullptr;
            if (derivedData) {
                std::copy(other.derivedData, 
                         other.derivedData + derivedSize, 
                         derivedData);
            }
        }
        return *this;
    }
    
    // 派生类移动赋值运算符
    Derived& operator=(Derived&& other) noexcept {
        std::cout << "Derived move assignment\n";
        if (this != &other) {
            // 调用基类移动赋值运算符
            Base::operator=(std::move(other));
            
            // 处理派生类成员
            delete[] derivedData;
            
            derivedData = std::exchange(other.derivedData, nullptr);
            derivedSize = std::exchange(other.derivedSize, 0);
        }
        return *this;
    }
    
    void print() const override {
        Base::print();
        std::cout << "Derived: size=" << derivedSize << "\n";
    }
};
 
// 演示切片问题
void demonstrateSlicing() {
    std::cout << "\n=== Slicing Problem ===\n";
    
    Derived d1(5, 10);
    Derived d2(3, 6);
    Base b(2);
    
    // 对象切片
    b = d1;  // 只调用Base::operator=,丢失派生类信息
    b.print();  // 只显示基类信息
    
    // 通过基类指针赋值
    Base* pb1 = new Derived(4, 8);
    Base* pb2 = new Derived(2, 4);
    *pb1 = *pb2;  // 仍然是切片!只调用Base::operator=
    pb1->print();  // 虚函数调用正确,但数据被切片
    
    delete pb1;
    delete pb2;
}

5.2 防止切片的设计

class NonSliceable {
    // 方法1:使基类抽象
    class AbstractBase {
    protected:
        int value;
        
    public:
        AbstractBase(int v = 0) : value(v) {}
        virtual ~AbstractBase() = default;
        
        // 纯虚函数使类抽象
        virtual void process() = 0;
        
        // 删除赋值运算符
        AbstractBase& operator=(const AbstractBase&) = delete;
    };
    
    // 方法2:私有赋值运算符
    class PrivateAssignBase {
    private:
        PrivateAssignBase& operator=(const PrivateAssignBase&) = default;
        
    protected:
        int value;
        
    public:
        PrivateAssignBase(int v = 0) : value(v) {}
        virtual ~PrivateAssignBase() = default;
    };
    
    // 方法3:使用clone模式
    class Cloneable {
    protected:
        int value;
        
    public:
        Cloneable(int v = 0) : value(v) {}
        virtual ~Cloneable() = default;
        
        // 虚拟克隆函数
        virtual std::unique_ptr<Cloneable> clone() const = 0;
        
        // 删除赋值运算符
        Cloneable& operator=(const Cloneable&) = delete;
    };
    
    class CloneableDerived : public Cloneable {
    private:
        double extra;
        
    public:
        CloneableDerived(int v = 0, double e = 0.0) 
            : Cloneable(v), extra(e) {}
        
        std::unique_ptr<Cloneable> clone() const override {
            return std::make_unique<CloneableDerived>(*this);
        }
    };
};

六、特殊情况和最佳实践

6.1 自赋值的处理

class SelfAssignment {
private:
    int* data;
    size_t size;
    
public:
    // 方法1:传统的自赋值检查
    SelfAssignment& operator=(const SelfAssignment& other) {
        if (this != &other) {  // 自赋值检查
            delete[] data;
            size = other.size;
            data = new int[size];
            std::copy(other.data, other.data + size, data);
        }
        return *this;
    }
    
    // 方法2:Copy-and-Swap(自动处理自赋值)
    SelfAssignment& operator=(SelfAssignment other) {  // 按值传递
        swap(other);  // 自赋值安全
        return *this;
    }
    
    // 方法3:先分配再释放(异常安全)
    SelfAssignment& operator=(const SelfAssignment& other) {
        // 不需要自赋值检查
        int* newData = new int[other.size];
        std::copy(other.data, other.data + other.size, newData);
        
        delete[] data;
        data = newData;
        size = other.size;
        
        return *this;
    }
    
    void swap(SelfAssignment& other) noexcept {
        using std::swap;
        swap(data, other.data);
        swap(size, other.size);
    }
};

6.2 性能优化技巧

class OptimizedAssignment {
private:
    char* buffer;
    size_t size;
    size_t capacity;
    
public:
    // 优化:重用已分配的内存
    OptimizedAssignment& operator=(const OptimizedAssignment& other) {
        if (this != &other) {
            // 如果容量足够,重用现有缓冲区
            if (capacity >= other.size) {
                std::copy(other.buffer, other.buffer + other.size, buffer);
                size = other.size;
            } else {
                // 需要重新分配
                char* newBuffer = new char[other.capacity];
                std::copy(other.buffer, other.buffer + other.size, newBuffer);
                
                delete[] buffer;
                buffer = newBuffer;
                size = other.size;
                capacity = other.capacity;
            }
        }
        return *this;
    }
    
    // 短字符串优化(SSO)
    class StringWithSSO {
    private:
        static constexpr size_t SSO_SIZE = 15;
        
        union {
            char sso[SSO_SIZE + 1];  // 小字符串直接存储
            char* ptr;                // 大字符串使用堆
        };
        
        size_t length;
        bool isSSO;
        
    public:
        StringWithSSO& operator=(const StringWithSSO& other) {
            if (this != &other) {
                // 清理当前状态
                if (!isSSO && ptr) {
                    delete[] ptr;
                }
                
                length = other.length;
                isSSO = other.isSSO;
                
                if (isSSO) {
                    std::copy(other.sso, other.sso + length + 1, sso);
                } else {
                    ptr = new char[length + 1];
                    std::copy(other.ptr, other.ptr + length + 1, ptr);
                }
            }
            return *this;
        }
    };
};

6.3 调试和测试

class AssignmentTesting {
private:
    static int copyCount;
    static int moveCount;
    int* data;
    size_t size;
    int id;
    
public:
    AssignmentTesting(size_t s = 0) 
        : size(s), data(s ? new int[s]() : nullptr), id(rand()) {
        std::cout << "Constructor [" << id << "]\n";
    }
    
    ~AssignmentTesting() {
        delete[] data;
        std::cout << "Destructor [" << id << "]\n";
    }
    
    // 拷贝赋值(带计数)
    AssignmentTesting& operator=(const AssignmentTesting& other) {
        std::cout << "Copy assignment [" << id << "] = [" << other.id << "]\n";
        ++copyCount;
        
        if (this != &other) {
            AssignmentTesting temp(other);
            swap(temp);
        }
        return *this;
    }
    
    // 移动赋值(带计数)
    AssignmentTesting& operator=(AssignmentTesting&& other) noexcept {
        std::cout << "Move assignment [" << id << "] = [" << other.id << "]\n";
        ++moveCount;
        
        if (this != &other) {
            delete[] data;
            
            data = std::exchange(other.data, nullptr);
            size = std::exchange(other.size, 0);
            // id不变,保持对象身份
        }
        return *this;
    }
    
    void swap(AssignmentTesting& other) noexcept {
        using std::swap;
        swap(data, other.data);
        swap(size, other.size);
        swap(id, other.id);
    }
    
    static void printStats() {
        std::cout << "\n=== Statistics ===\n";
        std::cout << "Copy assignments: " << copyCount << "\n";
        std::cout << "Move assignments: " << moveCount << "\n";
    }
    
    // 单元测试
    static void runTests() {
        std::cout << "\n=== Running Assignment Tests ===\n";
        
        // 测试拷贝赋值
        {
            AssignmentTesting a(10), b(20);
            b = a;
        }
        
        // 测试移动赋值
        {
            AssignmentTesting a(10), b(20);
            b = std::move(a);
        }
        
        // 测试自赋值
        {
            AssignmentTesting a(10);
            a = a;
        }
        
        // 测试链式赋值
        {
            AssignmentTesting a(10), b(20), c(30);
            c = b = a;
        }
        
        printStats();
    }
};
 
int AssignmentTesting::copyCount = 0;
int AssignmentTesting::moveCount = 0;

赋值运算符重载是C++中重要的特性,正确实现它对于资源管理至关重要。关键点包括:处理自赋值、确保异常安全、正确管理资源、支持移动语义,以及在继承层次中正确调用基类的赋值运算符。使用Copy-and-Swap惯用法可以简化实现并提供强异常保证。