- 是的,它们是相同的。派生类未声明虚拟对象并不能阻止其成为虚拟对象。实际上,如果方法在基类中是虚拟的,则无法阻止任何方法(包括析构函数)在派生类中是虚拟的。在> = C ++ 11中,可以使用
final
它来防止它在派生类中被覆盖,但这并不能防止它是虚拟的。
- 是的,如果派生类中的析构函数没有任何关系,则可以省略。它的虚拟与否无关紧要。
- 如果可能的话,我会忽略它。
virtual
为了清楚起见,我总是将关键字再次用于派生类中的虚函数。人们不必不必一直沿继承层次结构去弄清楚一个函数是虚拟的。此外,如果您的类是可复制的或可移动的,而不必声明自己的副本或移动构造函数,则声明任何类型的析构函数(即使您将其定义为default
)也将强制您声明副本并移动构造函数和赋值运算符(如果需要)它们,因为编译器将不再为您提供它们。
作为第3项的一点。在注释中已经指出,如果未声明析构函数,则编译器将生成默认的(仍然是虚拟的)。那个默认值是一个内联函数。
内联函数可能会使程序的更多内容暴露于程序其他部分的更改中,并使共享库的二进制兼容性变得棘手。同样,面对某些变化,增加的耦合会导致大量重新编译。例如,如果您确定确实要为虚拟析构函数实现,则需要重新编译每个调用它的代码。而如果您已在类主体中声明它,然后在.cpp
文件中将其定义为空,则无需重新编译即可进行更改。
我个人的选择仍然是在可能的情况下忽略它。在我看来,它会使代码混乱,而且编译器有时可以通过默认实现比空的实现更有效的工作。但是您可能会受到一些限制,因此这是一个糟糕的选择。