【Exceptional C++(23)】对象的生存期(二)
2018-01-30 本文已影响17人
downdemo
T& T::operator=(const T& other) {
if (this != &other) {
this->~T();
new (this) T(other);
}
return *this;
}
- 这段代码使徒用拷贝构造操作来实现拷贝赋值操作,以避免在两个地方重复相同代码,但存在许多问题
- 会切割对象,如果T是一个带有虚析构函数的基类,this->~T()就执行了错误操作,如果对一个派生类对象执行此操作,会销毁派生类对象并用T对象替代,这样会使派生类的编写者陷入痛苦,因为派生的赋值运算符通常是基于基类的赋值操作编写的
- 不是异常安全的,new会调用T的拷贝构造函数,如果这个构造函数可以抛出异常这个函数就不是异常安全的
- 使赋值操作变得低效
- 改变了正常的对象生存期,比如T在构造函数中获取了一个互斥锁或开启了数据库事务,在析构函数中释放锁或事务处理,锁或失误处理将会以不正确的方式被释放并在赋值操作中被重新获得
- 会对派生类产生破坏性影响
- 依赖于不可靠的指针比较操作,完全依赖于this != &other测试,考虑自赋值情形
- 应该反过来,拷贝构造操作应该以拷贝赋值操作实现,为了美观还可以编写一个私有的辅助函数做真正的工作
T::T(const T& other) {
do_copy(other);
}
T& T::operator=(const T& other) {
do_copy(other);
return *this;
}
T& T::do_copy(const T& other) {
...
}