【发布时间】:2020-07-13 23:21:28
【问题描述】:
使用IUnknown等接口的例子很多,在这个例子中是IDocHostUIHandler,但这并不重要 - 使用类似这样的代码:
class TDocHostUIHandlerImpl : public IDocHostUIHandler
{
private:
ULONG RefCount;
public:
TDocHostUIHandlerImpl():RefCount(0){ }
// IUnknown Method
HRESULT __stdcall QueryInterface(REFIID riid, void **ppv) {
if (IsEqualIID(riid,IID_IUnknown))
{
*ppv = static_cast<IUnknown*>(this);
return S_OK;
}
else if (IsEqualIID(riid, IID_IDocHostUIHandler)) {
*ppv = static_cast<IDocHostUIHandler*>(this);
return S_OK;
}
else {
*ppv = NULL;
return E_NOINTERFACE;
}
}
ULONG __stdcall AddRef() {
InterlockedIncrement((long*)&RefCount);
return RefCount;
}
ULONG __stdcall Release() {
if (InterlockedDecrement((long*)&RefCount) == 0) delete this;
return RefCount;
}
我的问题是Release() 方法使用delete this 删除接口实现,但之后return RefCount 不再引用内存中的有效对象(它访问已删除的内存)。
我认为应该是这样的
ULONG __stdcall Release() {
if (InterlockedDecrement((long*)&RefCount) == 0) { delete this; return 0; }
return RefCount;
}
这也不会触发我使用的资源泄漏工具(C++ Builder 中的 Codeguard)。那么为什么这么多例子都使用第一个版本,我在这里遗漏了什么?
还是只是在Release方法结束后在Visual Studio等另一个编译器中调用了“删除这个”?
几个例子:
https://www.codeproject.com/Articles/4758/How-to-customize-the-context-menus-of-a-WebBrowser
【问题讨论】:
标签: c++ interface c++builder