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

Missing virtual destructor in base interface class?

本文关键字:虚拟 析构函数 接口      更新时间:2023-10-16

我有一个从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 项目是在其他几个环境中构建的,在这些环境中,此警告不会弹出...

在COM的上下文中,对象的生存期管理(以及相关的清理)使用IUnknownAddRef()Release()方法进行,通过引用计数

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

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

因此,我怀疑警告是MinGW工具链中某个错误。

不应修改引用的 Windows SDK 头文件中IUnknown的定义,不应在可能为目的定义的自定义 COM 接口中添加虚拟析构函数。