2014-12-04 80 views
1

我一直在通过阅读一些现有的代码来进行一些代码学习。我知道在非COM类型的接口上使用虚拟析构函数的重要性。我的意思是不是从IUKOWN或IInspectable派生出来的。IUknown Derived接口上的虚拟析构函数

但是,我无法理解为什么它不需要在COM接口上具有虚拟析构函数。

我已经定义了这样的

MIDL_INTERFACE("0D70D782-809D-403B-AC95-XXXXXX") 
IMyInterface : IUnknown 
{ 
    public: 
     virtual bool method1() = 0; 
     virtual int method2() = 0; 
} 

我的界面,并在同一时间我有犯规从IUnkown得出这样

class ISampleLogic 
    { 
     public: 
     virtual ~ISampleLogic() {}; 
     //some more methods 

    } 

为什么没有用于第一界面没有虚析构函数的另一个接口?

预先感谢

+1

通常,如果您不打算在接口上调用delete,则“接口”没有虚拟析构函数是可以的。虽然,如果是这样的话[可能是好的做法](http://www.gotw.ca/publications/mill18.htm)有一个受保护的析构函数。 – 2014-12-04 08:56:37

回答

2

IUnknown有一个称为Release()方法。其工作是减少对象的参考计数,并在参考计数降至零时销毁该对象。所以它作为析构函数。因此不需要显式析构函数。

如果你有一个IUnknown指针(说IUnknown* punk),你不应该delete,但调用Release()代替(punk->Release())。这是因为其他进程可能会在对象上引用计数。

这是下降到执行的接口,以确保整个对象被删除。如有必要,该实现可能包含具有虚拟析构函数的类。

+0

感谢您的回复,但punk-> Release()内部调用本身的删除(punk)。 (删除这个)。在这一点上,我们也正在调用delete,并且可能会遇到在Non com接口上调用的同样的删除问题。这是否意味着在非com接口中,在接口引用上调用delete并在com接口中对具体类引用调用delete?因此我们不会陷入这个问题。对不起,只是想在我的脑海中清除它。 – virusrocks 2014-12-04 08:32:10

+0

“punk-> Release()内部调用本身的删除(punk)。(删除此)”。你确定知道吗?那么用C++以外的语言编写的COM对象呢? – Bathsheba 2014-12-04 08:37:45

+0

它的实现和语言相关,但最终它会像在相应的语言中删除自己一样。那就是我为什么这么说的。 – virusrocks 2014-12-04 08:39:45

4

你的第一个代码片段定义了一个接口,另一个定义了一个不是接口的类(即使你把它称为“另一个接口”)。

MSDN

  • 可以从零个或多个基站接口继承:

    一个Visual C++接口可以被定义如下。

  • 无法从基类继承。
  • 只能包含公共纯虚方法。
  • 不能包含构造函数,析构函数或运算符。
  • 不能包含静态方法。
  • 不能包含数据成员;属性是允许的。

长话短说,接口不需要,并且不允许有虚析构函数。它是负责构建和销毁的托管实现,COM接口定义是一组方法及其语法的契约。

+0

我同意,我会补充说应该用IDL或VC++扩展COM关键字来定义接口。 – acelent 2014-12-04 20:09:34