MSDN > Home page del forum > Visual C++ General > CComPtr vs _com_ptr_t
Formula una domandaFormula una domanda
 

Con rispostaCComPtr vs _com_ptr_t

Risposte

  • mercoledì 1 luglio 2009 10.45Nibu ThomasMVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Con risposta
    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.
  • mercoledì 1 luglio 2009 12.11nobugzMVP, ModeratoreMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Con risposta
    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.

Tutte le risposte

  • mercoledì 1 luglio 2009 10.45Nibu ThomasMVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Con risposta
    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.
  • mercoledì 1 luglio 2009 10.49Olaf van der Spek Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     

    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.

  • mercoledì 1 luglio 2009 11.04Nibu ThomasMVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    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.
  • mercoledì 1 luglio 2009 12.11nobugzMVP, ModeratoreMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Con risposta
    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.
  • mercoledì 1 luglio 2009 12.20Viorel_MVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    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.

  • mercoledì 1 luglio 2009 12.43Olaf van der Spek Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    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.
  • giovedì 2 luglio 2009 22.14Giovanni DicanioMVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    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

  • giovedì 2 luglio 2009 22.45Brian MuthMVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    Giovanni has stated the most important differences, IMO.

    Always, always embed _com_ptr_t code inside a try...catch construct.

  • giovedì 2 luglio 2009 22.54Doug HarrisonMVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    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)
  • venerdì 3 luglio 2009 10.05OlafvdSpek Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    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?
  • venerdì 3 luglio 2009 10.07OlafvdSpek Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    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&:
    That's a very dangerous operator indeed. I guess containers are free to invoke operator&, but I'm not sure they do.
  • venerdì 3 luglio 2009 16.31Giovanni DicanioMVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    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

  • venerdì 3 luglio 2009 18.17Viorel_MVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     

    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).

  • venerdì 3 luglio 2009 18.34Doug HarrisonMVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    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)
  • venerdì 3 luglio 2009 20.34OlafvdSpek Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    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.
  • venerdì 3 luglio 2009 22.00Giovanni DicanioMVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    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

  • sabato 4 luglio 2009 11.32OlafvdSpek Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    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.
  • sabato 4 luglio 2009 15.11Giovanni DicanioMVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    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