A COM Smart Pointer






3.18/5 (19 votes)
Oct 15, 2001
2 min read

198864

1732
A wrapper class to any COM interface pointer.
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 exceptIUnknown
. 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.
CComPtr()
Simply constructor, do nothing.
CComPtr(INTERFACE* lPtr)
Construct a new
CComPtr
object with an existing interface pointer. After that this newCComPtr
object can be used as interface pointer itself.
CComPtr(IUnknown* pIUnknown, IID iid)
Construct a new
CComPtr
object with anIUnknown
pointer and an IID, which represents the interface you are interested in. Internally constructor will callpIUnknown->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 oldCComPtr
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 classCComPtr
.
Example:
CComPtr<IWavePciStream> m_wavePciStreamPtr; IWavePciStream* pWavePciStream = (IWavePciStream*)m_wavePciStreamPtr;
- (b) Operator
*
: Used to fetch interface object wrapped by classCComPtr
.
Example:
CComPtr<IWavePciStream> m_wavePciStreamPtr; IWavePciStream wavePciStream = *m_wavePciStreamPtr;
- (c) Operator
&
: Used to fetch the pointer to interface pointer wrapped by classCComPtr
.
Example:
CComPtr<IWavePciStream> m_wavePciStreamPtr; IWavePciStream** ppWavePciStream = &m_wavePciStreamPtr;
- (d) Operator
->
: Used to makeCComPtr
object act as aTRUE
interface pointer.
Example
CComPtr<IWavePciStream> m_wavePciStreamPtr; m_wavePciStreamPtr->AnyPciStreamMethods();
- (e) Operator
=
: Used to transfer an exsiting interface pointer information to a newCComPtr
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.
- In parameter is
CComPtr
has another three methods.
Attach
: Used to attach an existing interface pointer to aCComPtr
object.Detach
: Used to detach interface pointer from aCComPtr
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.