@nrailgun
        
        2015-09-14T07:05:44.000000Z
        字数 1452
        阅读 2336
    ::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 说了算么。
