class Base
{
virtual void foo() = 0;
//~Base(); <-- No destructor!
};
显然,Base
将会派生出来。那么,C ++是否说编译器生成的Base
析构函数必须是虚拟的?
谢谢!
答案 0 :(得分:6)
不,析构函数不会是virtual
,除非您将其标记为此类。原因很简单 - 几乎可以通过指针和引用进行调用,以及虚拟调用的方式和方式与是否使用new
创建对象无关。如果您不使用new
创建对象,则不必使用delete
,因此您不需要虚拟析构函数。
答案 1 :(得分:2)
没有。这接近证明析构函数不会自动变为虚拟:
#include <iostream>
struct BaseBase {
~BaseBase() {
std::cout << "~BaseBase\n";
}
};
struct Base : BaseBase
{
virtual void foo() = 0;
//~Base(); <-- No destructor!
};
struct Derived : Base {
void foo() { std::cout << "foo\n"; }
~Derived() {
std::cout << "~Derived\n";
}
};
int main() {
Base *p = new Derived();
delete p;
}
这个程序实际上有未定义的行为,但我强烈怀疑在你的实现上它不会打印“~Derived”。如果Base
有一个虚拟析构函数,那么就不会有未定义的行为,它会打印“~Derived”。
当然,它实际上并没有证明标准。您运行它的任何实现都可能毕竟不符合要求。但是,一旦你尝试了几个,你就会明白无论标准如何,你都需要指定一个虚拟的析构函数。
答案 2 :(得分:1)
不,不保证dtor是虚拟的。
当声明专门设计为派生的类时,其明确声明虚拟dtor的良好做法。这通常是一个彻头彻尾的设计缺陷。事实上,我想不出一个设计缺陷就是从基类中省略虚拟dtor的情况。
答案 3 :(得分:1)
没有。一个类可以有虚拟成员,可以派生,甚至可以用new
分配,并在没有虚拟析构函数的情况下用delete
删除。
非法(UB)要做的是,如果析构函数未声明为虚拟,则使用指向base 的指针使用delete
销毁派生实例。
当然,没有理由不声明虚拟析构函数,如果你的类是派生的。