Introduction
CComPtr
wraps any interface pointer and will call AddRef()
and Release()
properly. That is, you don't need to worry about controlling the lifetime of your interface pointer.
Details
- ATL does provide a Smart Pointer class named
CComQIPtr
. But it uses some ATL related funtion so that it can be used only in an ATL environment.
- VC does provide
_com_ptr_t
& _bstr_ptr_t
keywords to provide some kind of a wrapper. But it depends on the MS VC compiler, without which you can benefit.
- My
CComPtr
provides compiler unrelated features to wrap any interface pointer except IUnknown
. Later I will explain why this limitation comes.
Illustration
Note: INTERFACE
and piid
are passed into the class CComPtr
through template parameters.
CComPtr
has four constructors to meet different requirement.
Simply constructor, do nothing.
Construct a new CComPtr
object with an existing interface pointer. After that this new CComPtr
object can be used as interface pointer itself.
CComPtr(IUnknown* pIUnknown, IID iid)
Construct a new CComPtr
object with an IUnknown
pointer and an IID, which represents the interface you are interested in. Internally constructor will call pIUnknown->QueryInterface
to fetch interface pointer according to the IID.
CComPtr(const CComPtr<INTERFACE, piid>& RefComPtr)
This contsructor takes another existing CComPtr
object as parameter. After that, clone the old CComPtr
object.
CComPtr
has one destructor, which will release interface pointer.
~CComPtr(){ if (m_Ptr) { m_Ptr->Release(); m_Ptr = NULL; } }
CComPtr
has five operators.
- (a) Operator
INTERFACE*
: Returns interface pointer wrapped by class CComPtr
.
Example:
CComPtr<IWavePciStream> m_wavePciStreamPtr;
IWavePciStream* pWavePciStream = (IWavePciStream*)m_wavePciStreamPtr;
- (b) Operator
*
: Used to fetch interface object wrapped by class CComPtr
.
Example:
CComPtr<IWavePciStream> m_wavePciStreamPtr;
IWavePciStream wavePciStream = *m_wavePciStreamPtr;
- (c) Operator
&
: Used to fetch the pointer to interface pointer wrapped by class CComPtr
.
Example:
CComPtr<IWavePciStream> m_wavePciStreamPtr;
IWavePciStream** ppWavePciStream = &m_wavePciStreamPtr;
- (d) Operator
->
: Used to make CComPtr
object act as a TRUE
interface pointer.
Example
CComPtr<IWavePciStream> m_wavePciStreamPtr;
m_wavePciStreamPtr->AnyPciStreamMethods();
- (e) Operator
=
: Used to transfer an exsiting interface pointer information to a new CComPtr
object. This operator has three different parameter list.
- In parameter is
INTERFACE*
- In parameter is another
CComPtr
object.
- In parameter is an interface pointer to
IUnknown
, which will be used to query other interface pointer defined by piid.
CComPtr
has another three methods.
Attach
: Used to attach an existing interface pointer to a CComPtr
object.
Detach
: Used to detach interface pointer from a CComPtr
object.
Release
: Used to release wrapped interface pointer explicitly.
CComPtr
is implemented in pure C++. That is, it does not depend on any specific C/C++ compiler and can be compiled under any ANSI C/C++ compliant compiler. I have tested in VC++ 6.0. I do believe it works in GNU C/C++ and MAC CodeWarrior.