- 是的,它们是相同的。派生类不声明虚拟事物并不能阻止它虚拟化。实际上,如果在基类中是虚拟的,则无法阻止任何方法(包括析构函数)在派生类中虚拟化。在> = C++ 11中,您可以使用
final
来防止它在派生类中被重写,但这并不妨碍它成为虚拟的。
- 是的,如果派生类中的析构函数无关,可以省略它。它的虚拟与否并不重要。
- 如果可能,我会忽略它。为了清楚起见,我总是在派生类中使用
virtual
关键字作为虚函数。人们不应该一直沿着继承层次去找出函数是虚拟的。另外,如果你的类是可复制或可移动的,而不必声明你自己的副本或移动构造函数,那么声明任何类型的析构函数(即使你将其定义为default
)都会强制你声明副本并移动构造函数和赋值运算符因为编译器将不再为你提供它们。
作为一个小点,它已经指出的评论,如果析构函数未申报的编译器生成一个默认的项目3(这仍然是虚拟的)。而且默认的是内联函数。
内联函数可能会将更多程序暴露给程序其他部分的更改,并使共享库的二进制兼容性变得棘手。另外,面对某些类型的变化,增加的耦合可能导致大量的重新编译。例如,如果您决定确实需要虚拟析构函数的实现,那么每一段调用它的代码都需要重新编译。而如果你已经在类体中声明了它,然后在.cpp
文件中将其定义为空,那么你将很好地修改它而不用重新编译。
如果可能,我个人的选择仍然是省略它。在我看来,它混淆了代码,编译器有时可以通过一个空的实现默认实现,稍微高效一些。但是,你可能会受到限制,因此这是一个糟糕的选择。
你最后一句应该是“不应该”而不是“应该”。 – 2010-02-04 09:07:16
@Chris Lutz,我在这方面领先于你。现在它已被编辑为提交。 :-) – Omnifarious 2010-02-04 09:09:19
我不同意'省略'部分。在头文件中声明并在源代码中定义它(空体)并不需要太多花费。如果您这样做,您可以随时回来并添加一些步骤(日志记录?),而不会强制客户重新编译。 – 2010-02-04 09:21:54