繁体   English   中英

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

[英]what to do with the destructors in an interface

当我用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() {}

第一个版本写得更短
第二个是有吸引力的,因为界面的所有功能都是纯虚拟的

有什么理由我应该选择一种或另一种方法(或者可能是第三种方法)?
谢谢

据我所知,使虚函数为纯虚拟的目的是强制派生类为其提供实现,或者通过在Derived::f() 显式编写Base::f()来选择默认实现。

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

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

但是,如果您只在Base 虚拟中创建所有函数, 而不是 虚拟,并为它们提供实现(实际上您要提供),同时您想要生成Base 抽象类型 ,那么在其中使用虚拟析构函数Base唯一的解决方案:

class Base
{
public:
   virtual void f() {}; //not pure virtual
   virtual ~Base() = 0; //pure - makes Base abstract type!
};

Base::~Base() {} //yes, you have to do this as well.

Base *pBase = new Base(); // error - cannot create instance!

希望有所帮助。

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

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

除非你有什么理由想要强迫这个,否则我会选择第一个案例。

好的,发现了一个链接,所以我想提一下它作为答案:

内联虚拟功能真的没有意义吗?

如果根本没有非内联函数存在(并且在一个实现文件中定义而不是在头部中定义),我已经看到了不发出任何v表的编译器。 他们会抛出错误,比如缺少vtable-for-class-A或类似的东西,你会像我一样困惑。

实际上,这与标准不一致,但它确实发生了考虑将至少一个虚函数放在标题中(如果只是虚拟析构函数),这样编译器就可以在该位置为类发出vtable。 我知道它发生在一些版本的gcc上。 Johannes Schaub

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM