Table of contents
1.
Introduction
2.
CComPtr Class
2.1.
Syntax
2.2.
Parameters
2.3.
Members
2.3.1.
Public Constructor
2.3.2.
Public Operators
2.4.
Inheritance Hierarchy
3.
CComPtrBase Class
3.1.
Syntax
3.2.
Parameters
3.3.
Members
4.
Public destructor
5.
Public Methods
5.1.
CComPtrBase::Advise
5.2.
CComPtrBase::Attach
5.3.
CComPtrBase::CoCreateInstance
5.4.
CComPtrBase::CopyTo
5.5.
CComPtrBase::Detach
5.6.
CComPtrBase::IsEqualObject
5.7.
CComPtrBase::QueryInterface
5.8.
CComPtrBase::Release
5.9.
CComPtrBase::SetSite
6.
Public Operators
6.1.
CComPtrBase::operator T*
6.2.
CComPtrBase::operator !
6.3.
CComPtrBase::operator &
6.4.
CComPtrBase::operator *
6.5.
CComPtrBase::operator <
6.6.
CComPtrBase::operator ==
6.7.
CComPtrBase::operator ->
7.
Public data members
8.
Frequently Asked Questions
8.1.
What is an interface pointer?
8.2.
What is a COM method?
8.3.
What is the use of CComPtr over CComQIPtr in COM?
8.4.
Which compiler is used to compile ComPtr?
9.
Conclusion
Last Updated: Mar 27, 2024
Medium

Memory Management Class-CComPtr and CComPtrBase

Author Yukti Kumari
1 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Memory management is the process by which we manage computer resources and memory intending to improve the performance of the system.

The Component Object Model(COM) is a technology that enables interaction between objects across processes and computers. It consists of interface pointers.

CComPtr and CComPtrBase

In this article, we will learn about the memory management classes -   CComPtr and CComPtrBase, including their syntax, parameters, members, constructors, etc., along with some examples to get a practical understanding.

CComPtr Class

The CComPtr Class is a smart pointer class that manages COM interface pointers. It is derived from the class CComPtrBase. It performs automatic reference counting, which helps to eliminate memory leaks. 

You need the header file “atlbase.h” in order to use the class CComPtr.

Syntax

Let's see the syntax of the class below. 

template<class T>
class CComPtr

Parameters

The class takes only one parameter, T
T is a COM interface that specifies the pointer type that we are going to store.

Members

The members of the class are as follows:

Public Constructor

CComPtr::CComPtr
The CComPtr class defines the constructor as:

CComPtr() throw ();
CComPtr(T* lp) throw ();
CComPtr (const CComPtr<T>& lp) throw ();

 

The parameters of the constructor are as follows:

  • lp 
    It initializes the interface pointer.
  • T
    It is a COM interface. 
     

Let's see some of the important characteristics of the constructor below:

  • If you pass a null pointer to the constructor, then the constructor calls Addref on lp.
     
  • When a CComPtr object gets destroyed, its non-null-owned object gets a Release Call. 
     
  • The new objects which are assigned to the CComPtr object are also released upon the destruction of the CComPtr object.

Public Operators

CComPtr::operator = 
It is known as the assignment operator, which assigns a pointer to the member pointer.
We can see the syntax of the assignment operator as:

T* operator= (T* lp) throw ();
T* operator= (const CComPtr<T>& lp) throw ();


The operator returns a pointer to the updated CComPtr object. 
When we perform the assignment operation, it calls Addref for the new object and releases the existing object if it exists.

Inheritance Hierarchy

The class CComPtr is derived from CComPtrBase.

CComPtrBase Class

The CComPtrBase class uses COM-based memory routines for providing the basis for smart pointer classes.  

You need the header file “atlcomcli.h” in order to use the class CComPtrBase.

Syntax

Let's see the syntax of the class below.

template <class T>
class CComPtrBase

Parameters

The class takes only one parameter, T, representing the object type that the smart pointer will reference.

Members

CComPtrBase class consists of constructors, destructors, public methods, and Public operators as class members. 
We will see each of them in detail in the upcoming sections of the blog. 

Public destructor

CComPtrBase::~CComPtrBase
The syntax for the destructor is:

~CComPtrBase() throw();


It releases the interface to which the CComPtrBase points.

Public Methods

In this section, we will see the various public methods present in the class.

Method Name

Description

CComPtrBase::Advise

Creates a connection between the CComPtrBase's connection point and a client's sink.

CComPtrBase::Attach

Takes ownership of an existing pointer.

CComPtrBase::CoCreateInstance

Creates an object of the class associated with a specified Class ID or Program ID.

CComPtrBase::CopyTo

Copies the CComPtrBase pointer to another pointer variable.

CComPtrBase::Detach

Releases ownership of a pointer.

CComPtrBase::IsEqualObject

Checks if the specified IUnknown points to the same object associated with the CComPtrBase object.

CComPtrBase::QueryInterface

Returns a pointer to a specified interface.

CComPtrBase::Release 

Releases the interface.

CComPtrBase::SetSite

Sets the site of the CComPtrBase object to the IUnknown of the parent object.

CComPtrBase::Advise

This method creates a connection between the CComPtrBase's connection point and a client's sink.

The function prototype is:

HRESULT Advise(
    IUnknown* pUnk,
    const IID& iid,
    LPDWORD pdw) throw();

 

It takes three parameters, pUnk, iid, and pdw:

  • pUnk - It is a pointer to the client's IUnknown
     
  • iid - It specifies the GUID of the connection point, which is the same as the outgoing interface managed by the connection point.
     
  • pdw - It is a pointer to the cookie that uniquely identifies the connection

 

The method Advise returns S_OK on success, and in case of failure, it returns HRESULT. 

CComPtrBase::Attach

This method helps to take ownership of an existing pointer.

The function prototype is:

void Attach(T* p2) throw();

 

It takes one parameter, p2, whose ownership will be taken by the CComPtrBase object.

Note:

Attach calls CComPtrBase::Release on the existing CComPtrBase::p member variable and then assigns p2 to CComPtrBase::p. After taking ownership of the pointer we pass as a parameter, it deletes the pointer along with any allocated data if the reference count on the object goes to 0.

CComPtrBase::CoCreateInstance

This method creates an object of the class associated with a specified Class ID or Program ID.

The function prototype is:

HRESULT CoCreateInstance(
    LPCOLESTR szProgID,
    LPUNKNOWN pUnkOuter = NULL,
    DWORD dwClsContext = CLSCTX_ALL) throw();

 

and

HRESULT CoCreateInstance(
    REFCLSID rclsid,
    LPUNKNOWN pUnkOuter = NULL,
    DWORD dwClsContext = CLSCTX_ALL) throw();


The method parameters are:

  • szProgID - It is a pointer to a ProgID used for recovering the CLSID.
     
  • pUnkOuter - It can be NULL or non-NULL. If it's NULL, it means that the object is not being created as part of an aggregate. On the other hand, if it is non-NULL, it is a pointer to the aggregate object's IUnknown interface (the controlling IUnknown).
     
  • dwClsContext - It refers to the context in which the code managing the newly created object will run.
     
  • rclsid - It is the CLSID associated with the data and code used for creating the object.

 

On success, the method returns S_OK or REGDB_E_CLASSNOTREG. On failure, it returns CLASS_E_NOAGGREGATION, CO_E_CLASSSTRING, or E_NOINTERFACE. 

Note:

There are two forms of the CoCreateInstance method. The first form uses CLSIDFromProgID to recover the CLSID. Both the forms then call CoCreateClassInstance.

If CComPtrBase::p is not NULL, as assertion error occurs in debug builds.

CComPtrBase::CopyTo

This method copies the CComPtrBase pointer to another pointer variable and increments the reference count of the CComPtrBase::p member variable.

The function prototype is:

HRESULT CopyTo(T** ppT) throw();

 

It takes one parameter, ppT, which specifies the address of the variable that will receive the CComPtrBase pointer.

On success, it returns S_OK; else, it returns E_POINTER.

Note:

If ppT is equal to NULL, it returns HRESULT and during debug build assertion error occurs when ppT is NULL.

CComPtrBase::Detach

It releases ownership of a pointer and returns a copy of the pointer by setting the CComPtrBase::p data member variable to NULL

The function prototype is:

T* Detach() throw();

CComPtrBase::IsEqualObject

It checks if the specified IUnknown points to the same object associated with the CComPtrBase object.

The function prototype is:

bool IsEqualObject(IUnknown* pOther) throw();

 

It takes one parameter, pOther, the IUnknown*, to be used for comparison. 
If the objects are equal, it returns true else, false.

CComPtrBase::QueryInterface

It returns a pointer to a specified interface and calls IUnknown::QueryInterface.

The function prototype is:

template <class Q> HRESULT QueryInterface(Q
** pp) const throw();

 

It takes two parameters:

  • Q - It is the object type for which we require the interface pointer.
  • pp - It specifies the address of the output variable for receiving the requested interface pointer.


On success, it returns S_OK; else, it returns E_NOINTERFACE.

Note:

If pp is not NULL, an assertion error occurs in debug builds.

CComPtrBase::Release

It releases the interface and sets the CComPtrBase::p to NULL.

The function prototype is:

void Release() throw();

CComPtrBase::SetSite

This method helps to set the site of the CComPtrBase object to the IUnknown of the parent object and calls AtlSetChildSite.

The function prototype is:

HRESULT SetSite(IUnknown* punkParent) throw();

 

The function parameter punkParent points to the IUnknown interface of the parent.

It returns S_OK on success or an error HRESULT on failure.

Public Operators

Following are the operators present in the class CComPtrBase.

Operator Symbol 

Operator Name

CComPtrBase::operator T*

The cast operator.

CComPtrBase::operator !

The NOT operator.

CComPtrBase::operator &

The address-of & operator.

CComPtrBase::operator *

The pointer-to * operator.

CComPtrBase::operator <

The less-than operator.

CComPtrBase::operator ==

The equality operator.

CComPtrBase::operator ->

The pointer-to-members operator.

CComPtrBase::operator T*

The cast operator returns a pointer to the object data type defined in the class template.

The operator is defined as:

operator T*() const throw();

CComPtrBase::operator !

It is the NOT operator and returns true if the CComHeapPtr pointer is equal to NULL, false otherwise.

The operator is defined as:

bool operator!() const throw();

CComPtrBase::operator &

This is known as the “address of” operator, which returns the address of the object pointed to by the CComPtrBase object.

The operator is defined as:

T** operator&() throw();

CComPtrBase::operator *

This is the pointer operator which returns the value of CComPtrBase::p.

The operator is defined as:

T& operator*() const throw();

CComPtrBase::operator <

The less-than operator returns true if the pointer managed by the current object is less than the pointer to which it's being compared.

The operator is defined as:

bool operator<(T* pT) const throw();

CComPtrBase::operator ==

This is the equality operator, and it returns true if CComPtrBase and pT point to the same object and false otherwise.

The operator is defined as:

bool operator== (T* pT) const throw();

CComPtrBase::operator ->

 This is known as the pointer-to-member operator used for returning the value of the CComPtrBase::p data member variable.

The operator is defined as:

_NoAddRefReleaseOnCComPtr<T>* operator->() const throw();

Public data members

It consists of one data member, CComPtrBase::p, which is the pointer data member variable.

Frequently Asked Questions

What is an interface pointer?

An interface pointer is a pointer to an object instance that points, in turn, to the implementation of each method in the interface. 

What is a COM method?

Component Object Model (COM) is a binary-interface standard for software components introduced by Microsoft.

What is the use of CComPtr over CComQIPtr in COM?

CComPtr is used for managing objects that support some interface while CComQIPtr is for cases when we want to call QueryInterface() in a convenient manner to find if an interface is supported:

Which compiler is used to compile ComPtr?

CComPtr is implemented in pure C++. It does not depend on any specific C/C++ compiler and can be compiled under any ANSI C/C++ compliant compiler.

Conclusion

In this article, we learned about the memory management classes CComPtr and CComPtrBase, their syntax, parameters, members, constructors, etc.

We hope this blog has helped you enhance your knowledge of the memory management class CComPtr and CComPtrBase.

Check out these useful blogs on ATL - 

 

Refer to our guided paths on Coding Ninjas Studio to learn more about DSA, Competitive Programming, JavaScript, System Design, etc. Enroll in our courses and refer to the mock test and problems available, interview puzzles, take a look at the interview experiences, and interview bundle for placement preparations.

Do upvote our blog to help other ninjas grow

Happy Reading!!‍

Live masterclass