[Effective C++]条款11:在operator= 中处理“自我赋值”

1、operator= 中的自我赋值

  • 自我赋值指的是一个对象将自己赋值给自己,例如a=a,这种做法虽然蠢,但语法是规范的。
  • 常见的自我赋值场景
    显式的自我赋值:
MyClass a;
a = a; // 直接自我赋值

通过引用或指针间接赋值
MyClass a;
MyClass* ptr = &a;
*ptr = a; // 通过指针间接自我赋值

2、自我赋值会导致的问题

  • 如果在赋值操作符中先释放当前对象的资源再赋值新的对象
class Bitmap {...}
class Widget{
    ...
private:
    Bitmap* pb;
}

Widget& Widget::operator=(const Widget& other){
    delete pb;
    pb = new Bitmap(*other.pb);
    return *this;
}
  • 问题1:如果operator=赋值操作符中参数other指向当前对象,的delete pb释放操作,会同时销毁other对象中的pb对象,然后在Bitmap的构造函数中传入*other.pb的值指向的是一个释放的对象。
  • 问题2:如果在执行 new Bitmap创建新对象时,调用malloc申请内存不足,导致函数抛出异常,则最终bp指向的是一个已销毁的指针。
    3、自我赋值检查
  • 在operator= 的实现中,首先检查是否为自我赋值,如果是直接返回*this
MyClass& operator=(const MyClass& other) {
    if (this == &other) { // 自我赋值检查
        return *this;
    }
    // 执行赋值操作
    delete[] data;
    data = new int[other.size];
    std::copy(other.data, other.data + other.size, data);
    return *this;
}

4、拷贝并交换处理

  • 通过创建一个临时副本并交换资源来处理赋值操作,这种处理方式感觉有点笨重,最好还是自己控制赋值操作符调用的对象。尽量避免自我赋值的额情况出现
MyClass& operator=(const MyClass& other) {
    MyClass temp(other); // 创建临时副本
    swap(*this, temp);   // 交换资源
    return *this;
}

void swap(MyClass& a, MyClass& b) {
    std::swap(a.data, b.data);
    std::swap(a.size, b.size);
}

思维导图笔记
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值