With technology like WinRT, Microsoft is putting C++ back on the scene. Every one knows that C++ as a native language produces a fairly
optimized code that will give your applications a good performance if properly used. However one of the drawbacks of C++ is that you have to
manage memory and resources of the system yourself.
For a generation of developers who were breastfed with manage languages like Java, C#, VB.NET, or Python, managing memory by themselves may appear tricky or even has-been!
As WinRT is based on good old COM and that one of the principles of COM is reference counting, I have tried to bring the safety of
reference counting of COM smart pointers to normal C++ class instances. This short article describes a reference counted smart
pointer that uses some of the principles of a COM component. It doesn't pretend to be a perfect solution but it brings some instance management
to the world of native programming and illustrates some of the principles of C++ development and memory management.
Remark: The given solution is for Visual Studio 2012 Premium. However the code for the smart
pointer can be used with any other Visual Studio version and with Windows XP to Windows 8. Visual Studio 2012 has a new unit test
framework for C++ code, which is why this solution needs this version.
It is better to have a good understanding of what a pointer and a reference means in C++ as opposed to a reference in a managed language
like C#, however the goal of this article is also to help developers who are not yet familiar with those concepts to understand them properly.
Other notions of C++ like
operator overloading, usage of the
different types of constructors like copy constructor, as well as a simple template class are used in this article. I will shortly explain
their usage and when it might be a bit tricky.
A simple architecture
My original requirement is to
provide an automatic mechanism to
manage the memory of an object referenced by a pointer and also support
a scenario where the pointer or reference is held by an object and the
object is deleted while its pointer is used by this other object. If
you don't support a counting mechanism, your program will crash as it
would try to use a pointer to an object that has been already deleted.
I have already found some
implementations of smart pointers with
reference counting but they impose that you use the smart pointer class
everywhere you would use a pointer, even in parameters. I wanted to use
a solution similar to the smart pointer of COM where you can still use
a normal pointer in the signature of the method when you pass this
pointer, but where everywhere you use a pointer to your object you put
it in a smart pointer class to manage the life of your reference.
I also tried to make it
compatible with using the
delete operator if
you don't manage the pointer with the smart pointer class.
There are two classes to
implement this smart pointer. One is
something similar to the
interface of COM but without the
method, and the other class is a template class very
similar to the
class of COM which is the smart pointer used to
manage COM references.
To be managed by my smart
pointer, a class must implement the
that defines the
C++ does't support constraints
for templates like C# so your template
definition may compile until you really instantiate with a concrete
class. In the case of
it expects the class used to
interface. In this article I may refer as interface a class that has
only pure virtual methods. Standard C++ doesn't have interface
keywords like Java or C#. The
interface keyword in C++/CX is an
extension of the language specific to Microsoft and the support of
WinRT in the language.
One of the paradigms of C++ is that it lets the developer completely
define a new type with a class. This new type will then behave exactly
like a native type of the compiler as long as every bit of it has been
created properly. This is why in C++ you can overload each and every
operator of a class, including the
operators as well as the cast
operators. Operators have a very precise behavior in C++
depending on if they apply to a pointer, a reference, or a value object.
For example a simple line of code may automatically invoke operators
and constructors without you realizing it.
The copy constructor in C++ is extremely important and most of the time
your classes must implement it properly, as the compiler is going to
invoke it implicitly and if you don't provide it, it will use a default
bit to bit copy which in most cases won't work.
This simple class diagram shows the hierarchy of classes and the
relations between them. The smart pointer class is a template class, I
described the fact that the template type is a
_refcnt_ptr with the
Let's dig into the smart pointer class.
The smart pointer class
The implementation I give here can be used as a base to create a more
complete smart pointer or maybe adapted to specific needs.
A smart pointer needs to behave like a regular pointer when you
use it so it needs to overload some useful operators.
I have overloaded the following ones:
-> so you can call the methods of the wrapped pointer as if
you were using it directly
* so you can write
= because the compiler may invoke it where you don't expect...
T* cast operator so you can automatically extract the underlying
It is also important to give a proper copy constructor to your smart
pointer as again the compiler is going to invoke it silently:
template<class T> class _refcnt_ptr sealed : public _refcnt
_refcnt_ptr() : m_ptr(nullptr)
_refcnt_ptr(const _refcnt_ptr<T>& otherPtr) : m_ptr(otherPtr.m_ptr)
_refcnt_ptr(T* ptr) : m_ptr(ptr)
T& operator* ()
_refcnt_ptr<T>& operator=(const _refcnt_ptr<T>& otherPtr)
if (this != &otherPtr)
m_ptr = otherPtr.m_ptr;
if (m_ptr != nullptr)
if (m_ptr != nullptr)
The complete code is given there but like I said it is a starting
point to illustrate the concept and when using it in different real
situations, it might need to be enhanced.
The wrapped pointer is of type
IRefCount, this is not
C++ templates are not type safe like in C# but it makes the code more
readable and the compiler will complain if you try to use it with a non
IRefCount class. You can write the same using
in place of
IRefCount*, the compiler will complain if your class
I have sealed the class as it is a stand-alone class that you won't
This smart pointer needs a
IRefCount based class to
work with. Let's
look at the code of this class.
class REFCNTDECL CRefCount : public IRefCount
int refCount; int refPtrCount;
void operator delete(void *ptr);
virtual void AddRef(bool isSmartPtr = false);
virtual void Release(bool isSmartPtr = false);
virtual bool CanReleaseRef();
This class does a little bit more than counting the number of
references of your object. It is also responsible to delete the object
when there is no more reference used. As a class that is managed by the
smart pointer must inherit from this class, when its method
called and the reference count is 0, the
Release method behaves like a
'suicide' method as it deletes the object itself.
Release() methods have
a parameter with a default value
set to false. This parameter is used to tell the reference counter if
it is used from a smart pointer. This information is used by the delete
operator implementation and the
It is useful for the following scenario:
_refcnt_ptr<CPerson> person = new CPerson();
_refcnt_ptr<CAddress> address = new CAddress(T_STREET, T_ZIP, T_CITY);
_refcnt_ptr<CAddress> refAddress = &person->GetAddress();
std::string city = refAddress->GetCity();
The pointer instance of
CPerson is managed by the
pointer, so when I call
person, it would delete the
person and the
CAddress object associated with it. However
because in the
CPerson class the
CAddress instance is
managed with a smart pointer the
CAddress I got from the
instance is still valid
and the program won't crash.
Another effect is as I have overloaded the delete operator and used
a counter of smart pointers monitoring this reference, the
doesn't delete the
CPerson instance, it lets the smart
pointer do it
when it is out of scope.
Previously I said that the
CAddress would be deleted
delete person, but because
delete is in fact not really
person instance, the address reference you have is
protected by two mechanisms.
I only tested a few scenarios and I'm pretty sure that I must have missed
some and that in a real application this smart pointer would have to
be... much more smarter!
Using the debugger on the above unit test method you can see how the
overloaded operators and constructors are called by the compiler on
a simple method call. For example put a break point in
person->SetAddress(address) and put some break points in
_refcnt_ptr code. You will be surprised how many lines of
the code are
invoked just for this simple call and the single line of code of that
Points of Interest
I have been working with COM and C++ for almost 10 years when COM
was a popular technology and Java was just starting to be used. Then .NET
came and COM was kind of put back to sleep. This was the era of managed
languages where the runtime took care of all the memory hassles
for you, well so you think. It's been now almost 10 years that I'm
working mostly with managed languages like C# and they definitely bring
some more safety in the memory management, but it brings out other
problems that are sometimes more difficult to solve because you don't
any more get a fine control on what you are doing.
So if you have to write WinRT components in C++, the C++/CX compiler
is going to take care of some of the plumbing of COM that was
troublesome in pure C++, but when it comes to your own C++ classes,
you'll have to manage the memory and the life of your objects by