Использование умного указателя CComObject
Я создаю COM-объект, вызывая его статический метод CreateInstance
, Но когда я покидаю свою программу, по крайней мере, в VS13, этот объект продолжает работать. Вот мой код:
CComObject< CMyAtlObject > * myAtlCOMObject = NULL;
HRESULT hr = CComObject< CMyAtlObject >::CreateInstance(&myAtlCOMObject);
ASSERT(SUCCEEDED(hr));
Я ожидал ~CComObject()
метод, который вызывается при выходе из области видимости, чего не происходит.
Я попытался поместить приведенный выше код в фигурные скобки, чтобы заставить вновь созданный объект выйти из области видимости.
Я пробовал звонить FinalRelease
на myAtlCOMObject
и удалось вручную вызвать Release
на myAtlCOMObject
, но программа все еще не перестала работать в VS13.
Что мне не хватает?
Вот код с встроенными комментариями:
{
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
Что мне не хватает?
Вам не хватает следующего:
CreateInstance
создает новый объект и получает необработанный указатель, который не собирается самоуничтожаться при выходе из области видимостиCreateInstance
создает объект в «нестабильном» состоянии с refcount, равным нулю, его самоопределение при управлении ссылками начинается после того, как что-то увеличивает refcount, по крайней мере, раз, а затем уменьшает его до нуля; CComQIPtr
выше пример этогоВозвращенный объект имеет счетчик ссылок, равный нулю, поэтому немедленно вызовите 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
В этом ответе также предусмотрена еще одна простая оболочка: Как лучше инициализировать счетчик ссылок для не создаваемого COM-объекта?.