我们在代码中大量使用了本地COM支持。一切都很好,除了我们不喜欢错误_com_raise_error()被调用而抛出_com_error异常这一事实。由于我们有自己的异常层次结构,因此捕获此_com_error是不便的-它不在我们的层次结构中,甚至也不继承自std::exception。

因此,我们需要覆盖_com_raise_error()。它本身很容易-只需在我们的代码中定义它,链接器就会与其链接。

但是,尚不清楚谁拥有IErrorInfo。签名是

void __stdcall _com_raise_error( HRESULT hr, IErrorInfo* info );

因此,调用该函数的人将负责在该函数返回后调用IErrorInfo::Release()。但是,如果我们在其中抛出异常并且控件将转移到其他地方,该函数将如何返回呢?

我检查了-称为AddRef(),然后在进入该函数时立即调用Release()-引用计数器为1。稍后,我们将所有权传递给构造的异常对象-它在其构造函数中调用AddRef(),在析构函数中调用Release()。我想这是不正确的,因为AddRef()会将引用计数增加到2,但是只有一个Release()会被调用(在异常析构函数中)。

我是否正确认为构造函数中的AddRef()会导致内存泄漏,或者是否存在某种内部机制根本不允许IErrorInfo对象泄漏?

最佳答案

_com_raise_error()不能返回。无论类型如何,它都必须引发一个异常。如果查看_com_raise_error()的默认实现,则引发的_com_error对象将拥有指定IErrorInfo对象的所有权。 _com_error的构造函数具有一个fAddRef参数,该参数的默认值为false,因此不会调用AddRef()。当_com_error对象被异常处理程序捕获的任何对象破坏后,就会调用Release(),从而释放IErrorInfo对象。

关于c++ - 谁拥有IErrorInfo的所有权?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1198829/

10-11 17:37