当指针超出范围时,CComObject :: CreateInstance创建的COM对象不会被销毁

rti*_*277 7 c++ com atl visual-studio-2013

使用智能指针CComObject我通过调用静态方法创建一个COM对象CreateInstance.但是当我离开我的程序时,至少在VS13中,该对象仍在运行.这是我的代码:

CComObject< CMyAtlObject > * myAtlCOMObject = NULL;
HRESULT hr = CComObject< CMyAtlObject >::CreateInstance(&myAtlCOMObject);
ASSERT(SUCCEEDED(hr));
Run Code Online (Sandbox Code Playgroud)

我期望在~CComObject()超出范围时调用该方法,而不会发生.

我尝试将上面的代码放在花括号中以强制新创建的对象超出范围.我试图调用FinalRelease上myAtlCOMObject,并成功地手动调用Release上myAtlCOMObject,但该方案仍然没有停止在VS13运行.

我错过了什么?

Rom*_* R. 8

以下是带内联注释的代码:

{
  CComObject<CMyAtlObject>* myAtlCOMObject = NULL;
  HRESULT hr = CComObject< CMyAtlObject >::CreateInstance(&myAtlCOMObject);
  ASSERT(SUCCEEDED(hr));
  // NOTE: Created new object with reference count of ZERO
  {
    const CComQIPtr<IMyAtlObject> pMyAtlObject = myAtlCOMObject;
    // NOTE: Reference count increased to ONE
  }
  // NOTE: ~CComQIPtr went out of scope and called IUnknown::Release 
  //       decrementing counter to ZERO; decrement to zero causes destruction
}
// NOTE: There is no ~CComObject call here on myAtlCOMObject going out of scope
//       since myAtlCOMObject is a raw pointer
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

您缺少以下内容:

  • CreateInstance 创建一个新对象并获取原始指针,该指针在离开范围时不会自毁
  • CreateInstance在refcount为零的情况下创建一个处于"不稳定"状态的对象,它在引用管理的自我描述开始之后,在一些增量引用后重新计数,然后将其递减为零; CComQIPtr上面就是一个例子

MSDN上CreateInstance:

返回的对象的引用计数为零,因此请立即调用AddRef,然后在完成后使用Release释放对象指针的引用.

你用什么而不是CComObject::CreateInstance?

我有一个帮助器模板类CObjectPtr,其行为类似于众所周知的方式,CComPtr并包装/管理本机C++类.

我的代码是:

CObjectPtr<CFoo> pFoo;
pFoo.Construct(); // Instantiates automatically adding reference
CFoo* pRawFoo = pFoo; // Acts as a pointer
CComPtr<IFoo> pFooInterface = pFoo; // Good for exposing inmepleted interafaces
CObjectPtr<CFoo> pAnotherFoo = pFoo; // Same instance proper reference counting
// ~CObjectPtr releases reference, destroys the object on last release
Run Code Online (Sandbox Code Playgroud)

此答案中还提供了另一个简单的包装器:如何更好地初始化非可创建COM对象的引用计数器?.