FREE Subscription to Dr. Dobb’s Digest: Same Great Content, New Digital Edition
Site Archive (Complete)
C++ Blog: A stray thought about intrusive smart pointers
C++
void main(void)

Calls, Returns and In-Between.

by Kevin Carlson
SELECTIVE IGNORANCE

Finding the Signal in the Noise

by Andrew Koenig
April 12, 2007

A stray thought about intrusive smart pointers

I've seen a lot of smart-pointer classes in C++, and they tend to divide into two categories: Intrusive smart pointers and non-intrusive ones. An intrusive pointer requires the author of the class to which it will point to accommodate the pointer, typically by deriving that class from a class designed as a helper to the smart-pointer class. For that reason, the non-intrusive pointers are often more interesting: You can attach one to an object of just about any type.

This flexibility typically comes at a cost: Non-intrusive smart pointers usually work by allocating a reference count as a separate object, which must then be maintained at a cost. Nevertheless, believing that people are generally more important than machines, I have long maintained that non-intrusive smart pointers should generally be preferred over the other kind.

Recently I saw an example that changed my thinking.

I am still not prepared to say that intrusive counters are always better than their counterparts--because of the burden they impose on class authors--but I realized only recently that intrusive smart pointers can do something that their non-intrusive counterparts cannot do easily.

Suppose you have an object with a smart pointer attached to it:

    Smart_pointer p = new T;

Then copying p will create a new smart pointer referring to the same object as the original:

    Smart_pointer q = p;

No problem so far. Suppose, however, that all you have is the address of the object to which the smart pointer is already attached, and you want to attach a new smart pointer to that object. For example, you have executed:

    Smart_pointer p = new T;
    T* tp = &*p;

and now you want to attach a new smart pointer to the object to which tp points without having direct access to p.

Unless the smart pointer is intrusive, I don't see how to accomplish this, even in principle. For such a smart pointer must locate not only the object but also the reference count associated with the object, and I can't see an easy way to map from the object to the corresponding reference count. If the smart pointer is intrusive, the reference count is right there.

The solution to this problem, of course, is that if you are using non-intrusive smart pointers, you should be even more careful to avoid handing raw addresses around, because you cannot convert those addresses into additional smart pointers. In particular, the obvious technique

    Smart_pointer q(tp);

will appear to work, but will fail horribly because it will delete the object while there is still a smart pointer attached to it.

I'm not sure there's any moral to this story except that working successfully with pointers, smart or otherwise, requires keeping one's wits about one.

Posted by Andrew Koenig at 12:57 PM  Permalink




 
INFO-LINK