@nrailgun
2015-09-14T15:05:44.000000Z
字数 1452
阅读 2110
::operator new
与 new
operator程序设计
C++ 的操作符重载是一个比较复杂的东西,而 new
是其中比较特殊的一个。
new
operatorC++ 使用 new
operator 动态申请空间:
int main()
{
string *s;
s = new string("!");
delete s;
}
new 表达式(new expression)具有两种形式。
分配内存,构造对象:
int main()
{
string *s;
s = new string("!");
return 0;
}
不分配内存,只构造对象:
int main()
{
string *s;
s = (string *) malloc(sizeof(string));
new (s) string("!");
return 0;
}
new
operator 的行为虽然 new expression 具有两种不同的行为,然而抽象而言,new
包含了以下操作:
::operator new
分配内存;什么是 ::operator new
呢?::operator new
是 C++ 标准库对于 new 表达式中分配内存行为的具体实现(注:表达式 2 不分配内存,见下文)。`
::operator new
::operator new
具有三个 prototype,定义在全局定义域:
// exception throwing (1)
void* operator new (std::size_t size) throw (std::bad_alloc);
// exception nothrow (2)
void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) throw();
// placement (3)
void* operator new (std::size_t size, void* ptr) throw();
“placement” 取“占位”之意。在 new
过程中,::operator new
(1)、(2) 被调用,分配内存;如果只构造而不分配内存,那么 placement (3) 版本将会被调用。Placement (3) 不分配内存,什么也不做,纯粹占位,所以称之为“placement”。
前两个版本可以被 overload 或者 replace,以实现自己的内存分配。一般而言,通过自己分配内存而提高程序效率比较困难,大部分情况下都是用来做内存泄露检测:
void *operator new (std::size_t sz)
{
log(time(), proc_stack(), sz);
return malloc(sz);
}
::operator new
属于动态链接注意 overload 和 replace 的区别。overload 是指为函数提供不同的形式参数或者模板参数,而 replace 是指覆盖原有定义。有同学质疑为何重复定义 ::operator new
不会导致链接器报错。这是因为默认情况下,链接器链接动态库不会管 multiple definition,而静态库默认对 multiple definition 报错。
= =|||,虽然我觉得这问题没啥意义,链接器爱怎么链接就怎么链接,这不都是 Richard Stallman 说了算么。