在基接口类中缺少虚拟析构函数?

时间:2015-01-20 16:19:45

标签: c++ windows gcc com mingw

我有一个来自IUnknown的类(public),其定义(来自MinGW 4.9.2中的文件include/unknwnbase.h)我粘贴在下面:

extern "C++" {
  MIDL_INTERFACE("00000000-0000-0000-C000-000000000046")
  IUnknown {
  public:
    BEGIN_INTERFACE
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) = 0;
    virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
    virtual ULONG STDMETHODCALLTYPE Release(void) = 0;

    template<class Q>
    HRESULT STDMETHODCALLTYPE QueryInterface(Q **pp) {
      return QueryInterface(__uuidof(Q), (void **)pp);
    }
    END_INTERFACE
  };
}

当我编译派生类时,我收到以下警告(在OpenCV项目中将其视为错误):

  

基类'struct IUnknown'具有可访问的非虚析构函数[-Werror = non-virtual-dtor]

我很难理解这是否是MinGW(缺少虚拟析构函数)的错误或其他可能以IUnknown派生的方式被规避的错误。 OpenCV项目建立在其他几个没有弹出警告的环境中......

1 个答案:

答案 0 :(得分:3)

在COM的上下文中,使用AddRef()的{​​{1}}和Release()方法,通过引用计数进行对象的生命周期管理(以及相关的清理) 。

每个COM对象都有一个与之关联的引用计数。当对象的引用计数达到0(例如,在某个COM接口指针上对象的多个客户端正确调用IUnknown之后),该对象将被销毁。换句话说,COM对象不会以通常的C ++方式调用,例如,基类指针上的Release()(因此在基类中需要适当的delete析构函数) (事实上​​,你不能只调用virtual来分配一个COM对象。需要更多的COM机制。)

换句话说,当您完成COM接口指针时,只需在其上调用new即可。因此,不需要在“基类”中定义虚拟析构函数,如Release()接口或其他COM接口。

所以,我怀疑警告是MinGW工具链中的某个错误。

应该在你引用的Windows SDK头文件中修改IUknown的定义,如果在自定义中添加虚拟析构函数, 您可以为您的目的定义的COM接口。