- 是的,它们是一样的。派生类没有声明一些虚拟的东西并不能阻止它成为虚拟的。事实上,如果派生类中的任何方法(包括析构函数)在基类中是虚拟的,则无法阻止它成为虚拟方法。在 >=C++11 中,您可以使用
final
它来防止它在派生类中被覆盖,但这并不妨碍它成为虚拟的。
- 是的,如果派生类中的析构函数无关,可以省略它。它是否是虚拟的并不重要。
- 如果可能的话,我会省略它。为了清楚起见,我总是在派生类中使用
virtual
关键字或虚函数。override
人们不应该一直走上继承层次结构来确定一个函数是虚拟的。此外,如果您的类是可复制或可移动的,而无需声明您自己的复制或移动构造函数,则声明任何类型的析构函数(即使您将其定义为default
)都将强制您声明复制和移动构造函数和赋值运算符(如果需要)它们作为编译器将不再为您放入它们。
作为第 3 项的一个小点。评论中已经指出,如果未声明析构函数,编译器会生成一个默认的(仍然是虚拟的)。而那个默认的是一个内联函数。
内联函数可能会将您的程序的更多部分暴露给程序其他部分的更改,并使共享库的二进制兼容性变得棘手。此外,面对某些类型的更改,增加的耦合会导致大量的重新编译。例如,如果您决定确实需要虚拟析构函数的实现,那么调用它的每一段代码都需要重新编译。而如果您在类主体中声明它,然后在.cpp
文件中将其定义为空,则无需重新编译即可更改它。
我个人的选择仍然是尽可能省略它。在我看来,它会使代码变得混乱,并且编译器有时可以使用默认实现而不是空的实现稍微更有效的事情。但是,您可能会受到一些限制,这使您做出了一个糟糕的选择。