我有一个来自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项目建立在其他几个没有弹出警告的环境中......
答案 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接口。