class Base
{
virtual void foo() = 0;
//~Base(); <-- No destructor!
};
显然,Base
会导出。那么,C++ 是否说编译器生成的析构函数Base
必须是虚拟的?
谢谢!
class Base
{
virtual void foo() = 0;
//~Base(); <-- No destructor!
};
显然,Base
会导出。那么,C++ 是否说编译器生成的析构函数Base
必须是虚拟的?
谢谢!
不,virtual
除非您将其标记为析构函数,否则析构函数不会。原因很简单 - 可以通过指针和引用进行虚拟调用,以及如何以及是否进行虚拟调用与是否使用new
. 如果你不创建对象,new
你就不需要delete
它们,所以你不需要虚拟析构函数。
它不是。这接近于证明析构函数不会自动变为虚拟:
#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”。
当然,它实际上并不能证明该标准的任何内容。您运行它的任何实现都可能不符合标准。但是一旦你尝试了一些,你就会明白无论标准怎么说,你都需要指定一个虚拟析构函数。
不,不保证 dtor 是虚拟的。
在声明专门设计为派生的类时,显式声明虚拟 dtor 是一种很好的做法。这通常是一个彻头彻尾的设计缺陷。事实上,我想不出从基类中省略虚拟 dtor 不是设计缺陷的情况。
不。一个类可以有虚拟成员,可以派生,甚至可以在没有虚拟析构函数new
的情况下分配和删除。delete
如果析构函数未声明为虚拟的,那么非法 (UB) 的做法是delete
使用指向基址的指针来销毁派生实例。
当然,如果您的类是要派生的,那么根本没有理由不声明虚拟析构函数。