我有一个从 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/