demko.ca

<< Back to Posts

Making your own smart pointers in C++

Aleksander Demko, May, 2008

Although C++ has no fancy, automatic dynamic memory management at the language level (yet), it does include (through templates and the RAII principles) the ability to make your own so-called "smart" pointers.

Smart pointers are small, custom classes that wrap a real pointer/dynamic object. Upon acquiring a pointer, they can increase reference counts and other tasks automatically and transparently. Similarly, when the smart pointer is destroyed, it can perform another, converse operation like decrementing a reference count, again, automatically.

Standard C++ includes a basic auto_ptr that is usable in certain simple cases. For more powerful, useful versions one has to turn to the boost libraries or write their own. Sometimes large libraries also provide their own custom smart pointers for users to use (like VTK) or at least to help out with implementation (wxWidgets, Qt for example). Suffice to say, because the C++ doesn't provide these smart pointers, everyone had to reinvent the concept for their own libraries, especially if they don't want to (or predated) use boost's versions. The next version of C++ will have new smart pointer classes borrowed from boost, but that's a ways off.

You may choose to write your own smart pointer classes. Some valid reasons include: not wanting to use boost's for some reason, you don't want to wait for the next version of C++, or you have some other (non-memory management related) operation you want to perform on pointer acquiring and releasing. Regardless, the situation may come up and I can offer a few tips.

When writing my own countr_ptr smart pointer for the Scopira library, I learnt a few things:

I built my class over many years, but if you need a quick reference on which operators to add, I suggest looking at the docs for boost::intrusive_ptr.

Also, if you make your own reference counting classes, make sure that you make the auto pointers symmetrical. That is, make them add a reference upon acquiring and subtract a reference on release. Asymmetrical systems (like those in GTK+ and VTK, in which objects are born with a reference) require confusing rules and special cases, and may prohibit you from using boost::intrusive_ptr as an alternative. In fact, I'd say if you can't use boost::intrusive_ptr with your classes, then you're doing something wrong :)