我想知道COM库中的标准做法是在COM接口上调用Addref,它是从函数返回的。例如:
IXMLDOMElement* domElement = NULL;
document_->get_documentElement(&domElement); // does get_documentElement() call Addref on domElement?
// ...
// do something with domElement
// ..
domElement.Release(); // correct?
// (btw. member variable document_ is of type CComPtr<IXMLDOMDocument2>
或使用智能指针:
CComPtr<IXMLDOMElement> domElement;
document_->get_documentElement(&domElement);
顺便说一下。我发现在“Windows Media 9系列”的MSXML文档中,它表示调用了Addref:http://msdn.microsoft.com/en-us/library/ms751196(v=vs.85).aspx
但是在官方文档中没有提到它: http://msdn.microsoft.com/en-us/library/ms759095(v=vs.85).aspx
答案 0 :(得分:2)
是的,在返回COM对象之前你应该使用addref,因为调用者将有一个引用该对象的新接口指针,因此引用计数需要增加1。这是规则,而不是例外。
记录内部addref是个例外,因为引用计数是COM的基础之一。可能这个文档是在很多这种方法的调用者不知道规则并导致太多内存泄漏的情况下编写的。
当你作为调用者不再需要接收到的对象时,你需要直接或间接调用Release(例如通过类析构函数),并停止使用引用指针(许多人将指针设置为null以防止悬空指针)。
答案 1 :(得分:2)
返回接口指针的函数必须在退出之前调用AddRef()
,而不是接收对象的函数。接收接口指针的函数必须按原样使用它,然后在其上调用Release()
。这意味着get_documentElement()
会调用AddRef()
,因此请勿自行调用。
在MS的COM文档中明确定义了谁 - 调用者或被调用者 - 负责在COM中进行引用计数和内存管理的规则: