- Smart Pointers 101
- The Deal
- Storage of Smart Pointers
- Smart Pointer Member Functions
- Ownership-Handling Strategies
- The Address-of Operator
- Implicit Conversion to Raw Pointer Types
- Equality and Inequality
- Ordering Comparisons
- Checking and Error Reporting
- Smart Pointers to const and const Smart Pointers
- Arrays
- Smart Pointers and Multithreading
- Putting It All Together
- Summary
7.6 The Address-of Operator
In striving to make smart pointers as indistinguishable as possible from their native counterparts, designers stumbled upon an obscure operator that is on the list of overloadable operators: unary operator&, the address-of operator.3
An implementer of smart pointers might choose to overload the address-of operator like this:
template <class T> class SmartPtr { public: T** operator&() { return &pointee_; } ... };
After all, if a smart pointer is to simulate a pointer, then its address must be substitutable for the address of a regular pointer. This overload makes code like the following possible:
void Fun(Widget** pWidget); ... SmartPtr<Widget> spWidget(...); Fun(&spWidget); // okay, invokes operator* and obtains a // pointer to pointer to Widget
It seems very desirable to have such an accurate compatibility between smart pointers and dumb pointers, but overloading the unary operator& is one of those clever tricks that can do more harm than good. There are two reasons why overloading unary operator& is not a very good idea.
One reason is that exposing the address of the pointed-to object implies giving up any automatic ownership management. When a client freely accesses the address of the raw pointer, any helper structures that the smart pointer holds, such as reference counts, become invalid for all purposes. While the client deals directly with the address of the raw pointer, the smart pointer is completely unconscious.
The second reason, a more pragmatic one, is that overloading unary operator& makes the smart pointer unusable with STL containers. Actually, overloading unary operator& for a type pretty much makes generic programming impossible for that type, because the address of an object is too fundamental a property to play with naively. Most generic code assumes that applying & to an object of type T returns an object of type T*—you see, address-of is a fundamental concept. If you defy this concept, generic code behaves strangely either at compile time or—worse—at runtime.
Thus, it is not recommended that unary operator& be overloaded for smart pointers or for any objects in general. SmartPtr does not overload unary operator&.