Reputation: 4005
I have a question regarding the usage of COM smart pointer class CComPtr
. I was following an example from the documentation and it seems the code does not call CoCreateInstance()
on the CComPtr
(it merely declares it before assigning it value).
So I wrote a test program like this:
#include "stdafx.h"
#include "atlbase.h"
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
CComPtr<int> myint = nullptr;
if (myint == nullptr) {
std::cout << "yes" << std::endl;
}
return 0;
}
And it gives the following error in visual-studio 2013:
------ Build started: Project: ConsoleApplication2, Configuration: Debug Win32 ------ ConsoleApplication2.cpp c:\program files (x86)\microsoft visual studio 12.0\vc\atlmfc\include\atlcomcli.h(177): error C2227: left of '->Release' must point to class/struct/union/generic type type is 'int *' c:\program files (x86)\microsoft visual studio 12.0\vc\atlmfc\include\atlcomcli.h(175) : while compiling class template member function 'ATL::CComPtrBase::~CComPtrBase(void) throw()' with [ T=int ] c:\users\calvi_000\documents\visual studio 2013\projects\consoleapplication2\consoleapplication2\consoleapplication2.cpp(18) : see reference to function template instantiation 'ATL::CComPtrBase::~CComPtrBase(void) throw()' being compiled with [ T=int ] c:\program files (x86)\microsoft visual studio 12.0\vc\atlmfc\include\atlcomcli.h(317) : see reference to class template instantiation 'ATL::CComPtrBase' being compiled with [ T=int ] c:\users\calvi_000\documents\visual studio 2013\projects\consoleapplication2\consoleapplication2\consoleapplication2.cpp(10) : see reference to class template instantiation 'ATL::CComPtr' being compiled ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Why is it illegal to assign a nullptr
to a CComPtr
object ? Is there any method that we can use to check whether or not a CComPtr
owns any objects ? Will a call like if (myint == nullptr)
enough to check if this smart pointer does not own any object ?
Upvotes: 2
Views: 4539
Reputation: 596713
Why is it illegal to assign a nullptr to a CComPtr object ?
It is not. As Hans pointed out, CComPtr
can only be used with COM interfaces, int
is not a compatible type. That is what the compiler error is telling you:
error C2227: left of '->Release' must point to class/struct/union/generic type type is 'int *'
So the problem is not that you are assigning nullptr
, but that int
does not have a Release()
method, which CComPtr
requires. An IUnknown
(or derived) interface does have a Release()
method.
Is there any method that we can use to check whether or not a
CComPtr
owns any objects ? Will a call likeif (myint == nullptr)
enough to check if this smart pointer does not own any object ?
If you read the CComPtr
documentation more carefully, you would see that CComPtr
derives from CComPtrBase
, which implements operator!()
, operator T*()
and operator==()
operators (so CComPtr
will act like a raw pointer), as well as an IsEqualObject()
method:
int _tmain(int argc, _TCHAR* argv[])
{
CComPtr<IUnknown> myUnk = nullptr;
if (!myUnk) { // calls myUnk.operator!() ...
std::cout << "null" << std::endl;
else
std::cout << "not null" << std::endl;
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
CComPtr<IUnknown> myUnk = nullptr;
if (myUnk) { // calls myUnk.operator IUnknown*() ...
std::cout << "not null" << std::endl;
else
std::cout << "null" << std::endl;
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
CComPtr<IUnknown> myUnk = nullptr;
if (myUnk == nullptr) { // calls myUnk.operator==(IUnknown*) ...
std::cout << "null" << std::endl;
else
std::cout << "not null" << std::endl;
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
CComPtr<IUnknown> myUnk = nullptr;
if (myUnk.IsEqualObject(nullptr)) {
std::cout << "null" << std::endl;
else
std::cout << "not null" << std::endl;
}
return 0;
}
Upvotes: 10