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.