Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A COM Smart Pointer

0.00/5 (No votes)
22 Feb 2006 1  
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

  1. 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.
  2. 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.
  3. 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.

  • CComPtr()

Simply constructor, do nothing.

  • CComPtr(INTERFACE* lPtr)

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.
    1. In parameter is INTERFACE*
    2. In parameter is another CComPtr object.
    3. 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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here