void f() {
T t(1);
T& rt = t;
// #1:使用t或rt做一些事
t.~T();
new (&t) T(2);
// #2:使用t或rt做一些事
} // t被再次销毁
- #2处代码是安全合法的,但函数作为一个整体它不是异常安全的,且这是一个坏习惯
- 在调用T(2)时,T的构造函数有抛出异常的可能,如果T(2)抛出异常,在原来t所在的内存区域将不会有新的对象被构造,而在函数末尾T::~T()仍被正常调用,这样t被构造一次,却被销毁两次
- 如果出现在成员函数中,会充满危险
void T::f(int i) {
this->~T();
new (this) T(i);
}
// 现在可以说这已经不安全了,考虑下面代码
class U : /*...*/ public T { ... };
void f() {
A t(1);
B& rt = t;
// #1:使用t或rt做一些事
t.f(2);
// #2:使用t或rt做一些事
} // t被再次销毁
- 如果A是T,那么#2处代码仍然可行,即使B不是T(可能是T的基类),如果A是U,无论B是什么都是错的,因为对t.f()的调用将对象切割了,t.f()用属于另一个不同型别的对象替换了原来的对象,即函数使用了T而不是U
网友评论