CComPtr vs _com_ptr_t
- What's the difference between CComPtr and _com_ptr_t?
Why isn't _com_ptr_t::Release just a no-op when the pointer is NULL?
Réponses
- CComPtr is an ATL class is used with using ATL COM implementations. The other one is one of the few COM support classes to support non ATL COM development IMO.
The other classes similar to _com_ptr_t are
_bstr_t
_com_error
_com_ptr_t
_variant_t
Answer to second part of your question from MSDN...
Calls IUnknown::Release on the encapsulated interface pointer, raising an E_POINTER error if this interface pointer is NULL .
Microsoft MVP - Visual C++
Blog: http://nibuthomas.com
Posts are provided as is without warranties or guaranties.- ModifiéNibu ThomasMVPmercredi 1 juillet 2009 10:48
- ModifiéNibu ThomasMVPmercredi 1 juillet 2009 10:49
- Marqué comme réponseNancy ShaoMSFT, Modérateurmercredi 8 juillet 2009 03:08
- The IUnknown::Release() method doesn't return an HRESULT. No way to signal an error. Calling Release() on a null pointer is a bug in your code, not a bug in the wrapper.
Hans Passant.- Marqué comme réponseNancy ShaoMSFT, Modérateurmercredi 8 juillet 2009 03:11
Toutes les réponses
- CComPtr is an ATL class is used with using ATL COM implementations. The other one is one of the few COM support classes to support non ATL COM development IMO.
The other classes similar to _com_ptr_t are
_bstr_t
_com_error
_com_ptr_t
_variant_t
Answer to second part of your question from MSDN...
Calls IUnknown::Release on the encapsulated interface pointer, raising an E_POINTER error if this interface pointer is NULL .
Microsoft MVP - Visual C++
Blog: http://nibuthomas.com
Posts are provided as is without warranties or guaranties.- ModifiéNibu ThomasMVPmercredi 1 juillet 2009 10:48
- ModifiéNibu ThomasMVPmercredi 1 juillet 2009 10:49
- Marqué comme réponseNancy ShaoMSFT, Modérateurmercredi 8 juillet 2009 03:08
So besides the name there's basically no difference? Nice! :(
> raising an E_POINTER error if this interface pointer is NULL .
Why? A no-op in that case seems much more convenient.- Also the definitions of these classes go along with the tlb files and probably that's why they are called as COM support classes. Also their definition can be found in comdef.h too.
Microsoft MVP - Visual C++
Blog: http://nibuthomas.com
Posts are provided as is without warranties or guaranties. - The IUnknown::Release() method doesn't return an HRESULT. No way to signal an error. Calling Release() on a null pointer is a bug in your code, not a bug in the wrapper.
Hans Passant.- Marqué comme réponseNancy ShaoMSFT, Modérateurmercredi 8 juillet 2009 03:11
Why isn't _com_ptr_t::Release just a no-op when the pointer is NULL?
If you assign NULL or zero to a _com_ptr_t value, then this should work as no-op if the value is already empty. Otherwise it acts as Release.
Why isn't _com_ptr_t::Release just a no-op when the pointer is NULL?
If you assign NULL or zero to a _com_ptr_t value, then this should work as no-op if the value is already empty. Otherwise it acts as Release.
Ah, nice work around! Still, I'm curious why Release works as it does.What's the difference between CComPtr and _com_ptr_t?
One of the differences is that CComPtr is guaranteed not to throw exceptions, instead I think that _com_ptr_t can throw exceptions.
Moreover, you could put CComPtr in an STL container like std::vector using CAdapt class, instead I think that you can't do that with _com_ptr_t.
Giovanni
- Giovanni has stated the most important differences, IMO.
Always, always embed _com_ptr_t code inside a try...catch construct. Moreover, you could put CComPtr in an STL container like std::vector using CAdapt class, instead I think that you can't do that with _com_ptr_t.
IIRC, the reason for that is _com_ptr_t's funky destructive operator&:
operator& Releases any encapsulated interface pointer, replacing it with NULL , and returns the address of the encapsulated pointer. This allows the smart pointer to be passed by address to a function that has an out parameter through which it returns an interface pointer.
I understand the motivation, but way too cute, IMO.
Doug Harrison (Visual C++ MVP)What's the difference between CComPtr and _com_ptr_t?
One of the differences is that CComPtr is guaranteed not to throw exceptions, instead I think that _com_ptr_t can throw exceptions.
Moreover, you could put CComPtr in an STL container like std::vector using CAdapt class, instead I think that you can't do that with _com_ptr_t.
Giovanni
Why do you think those two things?
That's a very dangerous operator indeed. I guess containers are free to invoke operator&, but I'm not sure they do.Moreover, you could put CComPtr in an STL container like std::vector using CAdapt class, instead I think that you can't do that with _com_ptr_t.
IIRC, the reason for that is _com_ptr_t's funky destructive operator&:One of the differences is that CComPtr is guaranteed not to throw exceptions, instead I think that _com_ptr_t can throw exceptions.
Moreover, you could put CComPtr in an STL container like std::vector using CAdapt class, instead I think that you can't do that with _com_ptr_t.
Giovanni
Why do you think those two things?
Reading _com_ptr_t template class source code in <comip.h> (I'm using VS2008), you can note that in case of failures, _com_issue_error is called. As a consequence of that, a _com_error exception is thrown.
Instead, if you read CComPtr template definition in <atlcomcli.h> , you can note that CComPtr methods are marked as throw() , that means that these methods will not throw an exception.
(You may want to read "Exception Specifications " on MSDN.)
HTH,
Giovanni
- ModifiéGiovanni DicanioMVPsamedi 4 juillet 2009 14:57
I think that “operator &” is offered by both of _com_ptr_t and CComPtr classes and is not a clear impediment to use STL collections (excepting collections of pointers).
- They don't have to use it, but it is a requirement for containers that &t return T*, T being the type of object held by the container. See 23.1/3 in the standard and follow it to 20.1.3. In VC2008's STL, various iterators' operator-> use &* to obtain a pointer to the item, which is incompatible with _com_ptr_t. Other places to look include the use of placement new.
Doug Harrison (Visual C++ MVP) One of the differences is that CComPtr is guaranteed not to throw exceptions, instead I think that _com_ptr_t can throw exceptions.
Moreover, you could put CComPtr in an STL container like std::vector using CAdapt class, instead I think that you can't do that with _com_ptr_t.
Giovanni
Why do you think those two things?
Reading _com_ptr_t template class source code in <comip.h> (I'm using VS2008), you can note that in case of failures, _com_issue_error is called. As a consequence of that, a _com_error exception is thrown.
Instead, if you read CComPtr template definition in <atlcomcli.h> , you can note that CComPtr methods are marked as throw() , that means that these methods will not throw an exception.
(You may want to read "Exception Specifications " on MSDN.)
Doug answered about the problem of using _com_ptr_t in STL containers.
HTH,
Giovanni
Have you looked at CComPtrBase::operator*? CComPtr can throw too it seems.
Besides, doesn't _com_ptr_t only throw in case of bugs? I don't see a problem with that.Have you looked at CComPtrBase::operator*? CComPtr can throw too it seems.
Besides, doesn't _com_ptr_t only throw in case of bugs? I don't see a problem with that.
I read the use of ATLENSURE inside CComPtrBase::operator* implementation, and so yes it may throw.
I used to think that the ATL smart pointers like CComPtr were designed without exceptions in mind, but just considering HRESULT's as a way to signal errors.
I'm not sure (I'm not an ATL expert), but probably if _ATL_NO_EXCEPTIONS is defined, no exception will be thrown in release builds, though.
Note that I've never written that _com_ptr_t does a wrong thing in throwing exceptions; I just used to think that the ATL smart pointer classes like CComPtr had a different "philosophy" about error management, based on HRESULT's instead of exceptions; instead C++ COM support helper classes like _com_ptr_t used exceptions.
(The original question was about the difference(s) between CComPtr vs. _com_ptr_t.)
Note also that it seems that there are some contexts in which exceptions are not considered a good way of managing errors.
For example it seems that some of the core Windows developers like Larry Osterman do not use C++ exceptions in their code for particular technical reasons.
So, I think that having two different kind of smart pointer classes, one HRESULT-based and non-throwing, and another one exception-based is fine. The developer can use the right tool for the right job.
Giovanni
So, I think that having two different kind of smart pointer classes, one HRESULT-based and non-throwing, and another one exception-based is fine. The developer can use the right tool for the right job.
Eh, both use HRESULT for some operations. IMO the difference is *not* in the exceptions department.Moreover, you could put CComPtr in an STL container like std::vector using CAdapt class, instead I think that you can't do that with _com_ptr_t.
I'd like to rectify something I wrote.
I've never used _com_ptr_t in a STL collection using CAdapt, but after private communication with ATL and COM expert Igor Tandetnik, it seems that it is possible.
To be more precise, he pointed out that, due to broken implementation of _com_ptr_t::operator<, _com_ptr_t cannot be used as a key in collections like std::map (unless custom comparison is provided), but it can be used as value.
There is also a related thread here:
"_com_ptr_t in a C++ ordered container"
http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/b6bb8805-bea9-4e73-8d42-86d85da53f61
Thanks,
Giovanni

