条款九: 避免隐藏标准形式的new
因为内部范围声明的名称会隐藏掉外部范围的相同的名称,所以对于分别在类的内部和全局声明的两个相同名字的函数f来说,类的成员函数会隐藏掉全局函数
class x { public: void f(); // operator new的参数指定一个 // new-hander(new的出错处理)函数 static void * operator new(size_t size, new_handler p); }; void specialerrorhandler(); // 定义在别的地方 x *px1 = new (specialerrorhandler) x; // 调用x::operator new x *px2 = new x; // 错误!
在类里定义了一个称为“operator new”的函数后,会不经意地阻止了对标准new的访问。解决办法是在类里写一个支持标准new调用方式的operator new,它和标准new做同样
的事。这可以用一个高效的内联函数来封装实现。
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; // 调用 x::operator // new(size_t, new_handler) x* px2 = new x; // 调用 x::operator // new(size_t)
另一种方法是为每一个增加到operator new的参数提供缺省值(见条款24):
class x { public: void f(); static void * operator new(size_t size, // p缺省值为0 new_handler p = 0); // }; x *px1 = new (specialerrorhandler) x; // 正确 x* px2 = new x; // 也正确