虚拟析构函数是inheritance的吗?
如果我有一个虚拟析构函数的基类。 有一个派生类来声明一个虚拟析构函数吗?
class base { public: virtual ~base () {} }; class derived : base { public: virtual ~derived () {} // 1) ~derived () {} // 2) };
具体问题:
- 是1)和2)是一样的吗? 是2)自动虚拟,因为它的基础或是它“停止”虚拟?
- 如果没有任何关系,派生的析构函数可以省略吗?
- 声明派生析构函数的最佳做法是什么? 声明它是虚拟的,非虚拟的或者如果可能的话省略它?
- 是的,他们是一样的。 没有声明虚拟的派生类不会阻止它虚拟化。 事实上,没有办法阻止任何方法(包括析构函数)在派生类中虚拟化,如果它在基类中是虚拟的。
- 是的,如果派生类中的析构函数无关,则可以省略它。 而不pipe它是否虚拟。
- 如果可能,我会省略它。 为了清楚起见,我总是在派生类中使用
virtual
关键字作为虚函数。 人们不应该一直沿着inheritance层次去找出一个函数是虚拟的。
作为第3项的一个小点。在注释中已经指出,如果析构函数未声明,编译器会生成一个默认的(仍然是虚拟的)。 而这个默认的是一个内联函数。
内联函数可能会将更多程序暴露给程序其他部分的更改,并使共享库的二进制兼容性变得棘手。 另外,增加的耦合可能导致在某些types的变化中进行大量的重新编译。 例如,如果你决定真的想为虚拟析构函数实现一个实现,那么每一个调用它的代码都需要重新编译。 而如果你已经在类体中声明了它,然后在.cpp
文件中将其定义为空,那么你可以很好地修改它,而不用重新编译。
如果可能,我个人的select仍然是省略。 在我看来,它混淆了代码,编译器有时可以做一个稍微更有效的东西,默认的实现是空的。 但是,你可能会受到限制,这是一个糟糕的select。
一个虚拟的成员函数将隐含地重载这个函数的虚拟。
因此,1)中的虚拟是“可选的”,基类析构函数是虚拟的,所有子析构函数也是虚拟的。
- 与所有方法一样,析构函数也是自动虚拟的。 你不能阻止一个方法在C ++中是虚拟的(如果它已经被声明为虚拟的,也就是说,在Java中没有相应的'final')
- 是的,可以省略。
- 我会声明一个虚拟的析构函数,如果我打算让这个类被子类化,不pipe它是否inheritance另一个类,我也倾向于保持声明方法是虚拟的,即使它不是必需的。 如果你决定删除inheritance,这将保持子类的工作。 但我想这只是一个风格问题。
1 /是2 /是的,它将由编译器生成3 /声明它是虚拟的select应该按照你的约定重写虚拟成员 – 恕我直言,这里有好的论点,只要select一个,并按照它。
如果可能的话,我会省略它,但有一件事情可能会煽动你声明它:如果你使用编译器生成一个,它是隐式的内联。 有时候你想避免内联成员(例如dynamic库)。