Item 9: Avoid hiding the "normal" form of new
.
A declaration of a name in an inner scope hides the same name in outer scopes, so for a function f
at both global and class scope, the member function will hide the global
void f(); // global function
class X { public: void f(); // member function };
X x;
f(); // calls global f
x.f(); // calls X::f
This is unsurprising and normally causes no confusion, because global and member functions are usually invoked using different syntactic forms. However, if you add to this class an operator
new
taking additional parameters, the result is likely to be an
class X { public: void f();
// operator new allowing specification of a // new-handling function static void * operator new(size_t size, new_handler p); };
void specialErrorHandler(); // definition is elsewhere
X *px1 = new (specialErrorHandler) X; // calls X::operator new
X *px2 = new X; // error!
By declaring a function called "operator new" inside the class, you inadvertently block access to the "normal" form of new
. Why this is so is discussed in Item 50. Here we're more interested in figuring out how to avoid the
One solution is to write a class-specific operator
new
that supports the "normal" invocation form. If it does the same thing as the global version, that can be efficiently and elegantly encapsulated as an inline
class X { public: void f();
static void * operator new(size_t size, new_handler p);
static void * operator new(size_t size) { return ::operator new(size); } };
X *px1 = new (specialErrorHandler) X; // calls X::operator // new(size_t, new_handler)
X* px2 = new X; // calls X::operator // new(size_t)
An alternative is to provide a default parameter value (see Item 24) for each additional parameter you add to operator
new
:
class X { public: void f();
static void * operator new(size_t size, // note default new_handler p = 0); // value for p };
X *px1 = new (specialErrorHandler) X; // fine
X* px2 = new X; // also fine
Either way, if you later decide to customize the behavior of the "normal" form of new
, all you need to do is rewrite the function; callers will get the customized behavior automatically when they