请考虑以下
class base{
base();
~base();
}:
class derived : public base{
};
当派生对象被破坏并且派生类没有定义析构函数时,是否会自动调用基类析构函数?
否则,如果我在派生类中也有析构函数,我是否还需要显式调用基类析构函数?
class base{
base();
~base();
}:
class derived : public base{
derived();
~derived
base::~base(); //do I need this?
}
};
答案 0 :(得分:14)
在这种情况下会自动调用基类析构函数; you do not need to call it
但是,请注意在基类指针上通过delete
销毁对象并且析构函数不是virtual
时,结果将是未定义的行为(尽管你可能不会崩溃。)
始终在任何要派生的类中将析构函数声明为virtual
。如果基类不需要有析构函数,那么无论如何都要包含一个空virtual
。
对于边缘情况,上述规则有一个例外:如果派生类不需要支持多态破坏,那么析构函数不需要是virtual
。在这种情况下,改为protected
是正确的; more details here,但请注意,这在实践中很少发生。
答案 1 :(得分:2)
当派生对象被破坏并且派生类没有定义析构函数时,是否会自动调用基类析构函数?
是的,在Derived类Destructor之后自动调用Base类析构函数,而不管是否明确定义了Derived类析构函数。
否则,如果我在派生类中也有析构函数,我是否也需要显式调用基类析构函数?
不,你不需要。
在C ++中不会有任何场景,除非使用placement new,否则必须显式调用析构函数。
答案 2 :(得分:1)
不,在这种情况下会自动调用基本析构函数,这与基本构造函数 的自动调用方式非常相似。
但是,请注意,如果您使用多态并通过基指针销毁,则应该确定析构函数是虚拟的,否则会破坏。
答案 3 :(得分:1)
你应该 永远不会从派生类析构函数 中调用基类析构函数。
原因是基类析构函数将在第二次自动调用,并以不会导致问题的方式编写析构函数是有问题的 - see this question。