例如:
class Foo : public Bar
{
~Foo()
{
// Do some complicated stuff
}
Foo &operator=(const Foo &rhs)
{
if (&rhs != this)
{
~Foo(); // Is this safe?
// Do more stuff
}
}
}
在继承和其他类似的事情上明确调用析构函数会产生什么意外后果吗?
有没有理由将析构函数代码抽象为void destruct()
函数并调用它?
答案 0 :(得分:5)
在最简单的情况下调用析构函数是一个坏主意,而在代码变得稍微复杂的那一刻,调用析构函数是一个可怕的。
最简单的情况是:
class Something {
public:
Something(const Something& o);
~Something();
Something& operator =(const Something& o) {
if (this != &o) {
// this looks like a simple way of implementing assignment
this->~Something();
new (this) Something(o); // invoke copy constructor
}
return *this;
}
};
这是一个坏主意。如果复制构造函数抛出,则会留下原始内存 - 那里没有对象。只有在赋值运算符之外,没有人注意到。
如果继承发挥作用,情况会变得更糟。让我们说Something
实际上是一个带有虚析构函数的基类。派生类的功能都是使用默认值实现的。在这种情况下,派生类的赋值运算符将执行以下操作:
此时,你有多个UB的实例相互堆积在一堆光辉的混乱之中。
所以是的。别这么做。
答案 1 :(得分:0)
绝对不是。
void f()
{
Foo foo, fee;
foo = fee; <-- a first foo.~Foo will be called here !
} <-- a second foo.~Foo will be called here and fee.~Foo as well !
正如您所看到的,您有3次调用析构函数而不是预期的2次调用。
你应该 NOT 在构造函数或非静态方法中使用* self- *析构函数。