如何处理界面中的析构函数

时间:2011-03-19 10:59:20

标签: c++ oop interface destructor

当我用C ++编写接口类时,我选择以下两个选项之一

class Interface
{
public:
   virtual R1 f1(p11, p12 , ...) = 0;
   ...
   virtual Rn fn(pn1, pn2 , ...) = 0;
   virtual ~Interface() {} 
}

class Interface
{
public:
   virtual R1 f1(p11, p12 , ...) = 0;
   ...
   virtual Rn fn(pn1, pn2 , ...) = 0;
   virtual ~Interface() = 0; 
}
Interface::~Interface() {}

第一个版本更短,可以写入 第二个是有吸引力的,因为接口的所有功能都是纯虚拟的

有什么理由我更喜欢一种或另一种方法(或者可能是第三种方法)?
感谢

4 个答案:

答案 0 :(得分:5)

据我了解,制作虚拟函数纯虚拟的目的是强制派生类为其提供实现,或者通过显式编写{选择默认实现Base::f()中的{1}}。

如果这是真的,那么制作虚拟析构函数Derived::f()的目的是什么?它是否强制派生类为pure virtual提供实现?派生类可以实现Base::~Base()吗?没有。

这意味着,带有Base::~Base()析构函数的第一个版本似乎足以满足 所有目的。毕竟,虚拟析构函数最常见的目的是客户端可以通过类型virtual的指针正确delete派生类的对象。

但是,如果您仅在Base* 虚拟中创建所有功能, 虚拟,并为它们提供实施(实际上你要提供),同时你想要Base 抽象类型,然后在{{1}中有一个虚拟析构函数}是唯一的解决方案:

Base

希望有所帮助。

答案 1 :(得分:2)

对我而言,dtor不是界面的一部分。 fi()在其他语言中会有类似物,而不是dtor。同样,您可以为fi()编写前置和后置条件,但不能写入dtor。这使得它只是一个C ++疣,第一种技术是处理它的最舒适的方法。

答案 2 :(得分:1)

在第一种情况下,派生类可以选择是否实现析构函数。 在第二种情况下,必须重写纯虚析构函数,因此派生类被强制实现析构函数。

除非你有什么理由要强制这样做,否则我会选择第一种情况。

答案 3 :(得分:1)

好的,找到了一个链接,所以我想提一下这个答案:

Are inline virtual functions really a non-sense?

  

我见过没有发出的编译器   任何v表,如果没有非内联函数   完全存在(并在一个中定义   实现文件而不是   标题然后)。他们会抛出错误   喜欢缺少vtable-for-class-A或   类似的东西,你会   像我一样混淆了地狱。

     

确实,这不符合   标准,但它发生如此考虑   至少放一个虚函数   不在标题中(如果只是虚拟   析构函数),这样编译器   可以为班级发出vtable   那个地方。我知道它发生了   某些版本的gcc。   (Johannes Schaub

它与你的第二个案例略有不同(建议实际上完全从头文件中取出函数,以免成为gcc问题的受害者)但我想我会提到它。 gcc的怪癖偶尔会咬人。