c++ - 基接口(interface)类中缺少虚拟析构函数?

标签 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 项目中被视为错误):

base class 'struct IUnknown' has accessible non-virtual destructor [-Werror=non-virtual-dtor]

我很难理解这是 MinGW 的错误(缺少虚拟析构函数)还是可以通过派生 IUnknown 的方式规避的其他问题。 OpenCV项目搭建在其他几个环境都没有弹出这个警告...

最佳答案

在 COM 的上下文中,对象的生命周期管理(和相关的清理)发生在使用 AddRef()Release() IUnknown 的方法,通过引用计数

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

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

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

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

关于c++ - 基接口(interface)类中缺少虚拟析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28050219/

相关文章:

c++ - 排除一种类型的模板

windows - 使用包含空格的变量路径从批处理文件调用 .exe

windows - Robocopy能否完全克隆C盘(操作系统盘)

c++ - 在特定变量上禁用 GCC "may be used uninitialized"

c - 如何防止 gcc 优化器产生不正确的位操作?

用于异步 HTTP 客户端的 C++ 库

c++ - std::map 发现在 C++ 中不起作用

C++ 从基类继承构造函数

python - Pyinstaller 不包含模块

gcc - 何时使用 gcc 标志 -nostartfiles?