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);
}
思维导图笔记

2268

被折叠的 条评论
为什么被折叠?



