如果我有一个带有虚拟析构函数的基类。派生类也有声明虚拟析构函数吗?
class base {
public:
virtual ~base () {}
};
class derived : base {
public:
virtual ~derived () {} // 1)
~derived () {} // 2)
};
具体问题:
- 1) 和 2) 相同吗? 2)是因为它的基础而自动虚拟还是它“停止”虚拟性?
- 派生析构函数如果无关的话可以省略吗?
- 声明派生析构函数的最佳实践是什么?声明它是虚拟的、非虚拟的还是如果可能的话省略它?
- 是的,它们是一样的。派生类不声明虚拟的东西并不能阻止它成为虚拟的。事实上,如果任何方法(包括析构函数)在基类中是虚拟的,则无法阻止它在派生类中成为虚拟的。在 >=C++11 中你可以使用
final
以防止它在派生类中被重写,但这并不能阻止它成为虚拟的。
- 是的,派生类中的析构函数如果无关的话可以省略。是否虚拟并不重要。
- 如果可能的话我会省略它。我总是使用
virtual
关键字或override
为了清楚起见,对于派生类中的虚函数。人们不应该必须沿着继承层次结构一路向上才能弄清楚函数是虚拟的。此外,如果您的类是可复制或可移动的,而无需声明您自己的复制或移动构造函数,则声明任何类型的析构函数(即使您将其定义为default
)将强制您声明复制和移动构造函数以及赋值运算符(如果您需要它们),因为编译器将不再为您添加它们。
作为第 3 项的一个小要点。注释中指出,如果未声明析构函数,编译器会生成默认析构函数(仍然是虚拟的)。默认函数是内联函数。
内联函数可能会将程序的更多部分暴露给程序其他部分的更改,并使共享库的二进制兼容性变得棘手。此外,面对某些类型的更改,增加的耦合可能会导致大量的重新编译。例如,如果您决定确实想要虚拟析构函数的实现,那么调用它的每一段代码都需要重新编译。而如果您在类主体中声明了它,然后在类中将其定义为空.cpp
文件,您可以更改它而无需重新编译。
我个人的选择仍然是尽可能忽略它。在我看来,它会使代码变得混乱,并且编译器有时可以使用默认实现而不是空实现来完成稍微更有效的事情。但你可能会受到一些限制,这使得这是一个糟糕的选择。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)