c++ new的三种形态

(1)new operator

new的第一种形态是new operator,它是语言内建的,不能重载。new operator完成以下三件工作:

1. allocate memory for this object.

2. call constructor to init that memory.

3. return the pointer of this object.

例如:string *pStr = new string(“Memory Management”);

它实际完成以下三件事:

// 1. 为string对象分配raw内存

void *memroy = operator new( sizeof(string) );

// 2. 调用构造函数初始化内存中的对象

call string::string() on memory

// 3. 获得对象指针

string *pStr = static_cast<string *>(memory);

第1步申请内存,通过operator new完成;第2步在指定的内存上调用构造函数初始化对象,通过placement new完成。这便是new的另外两种形态。

(2)operator new

operator new是普通操作符,和加减乘除操作符的地位一样,可以重载。

默认情况下,operator new尝试从堆上申请内存,如果成功则返回内存指针,如果失败会调用new_handler,然后继续重复前面过程,直到抛出异常(bad_alloc)为止。

operator new函数原型:void * operator new(size_t size);

operator new可以重载,可以为某个类单独重载,也可以全局重载(将改变所有operator new的行为方式)。如果重载了operator new,应该重载operator delete。

(3)placement new

(定位new)在已分配的原始内存中初始化一个对象。它与new的其他版本的不同之处在于,它不分配内存。相反,它接受指向已分配但未构造的内存的指针,并在该内存中初始化一个对象。placement new表达式能够在特定的、预分配的内存地址上构造一个对象。

placement new是c++标准库的一部分,使用时需包含<new>头文件。

void *s = operator new( sizeof(A) );
A *p = (A*)s;
new(p) A(2013); // p->A::A(2013);
// processing code…
p->~A();

如果显示的调用placement new,也应该显示的调用与之对应的placement delete:p->~A();。这份工作本来应该由编译器自动完成:在使用new operator时,编译器会自动生成调用placement new的代码。所以,除非特别必要,不要直接使用placement new。只有当默认的new operator对内存的管理不能满足需要,希望自己手动管理内存时,才考虑使用placement new。就像STL中的allocator一样,它借助placement new来实现更灵活有效的内存管理。

【学习资料】 《编写高质量代码 c++》 《thinking in c++》

posted on 2013-03-23 10:20  zhuyf87  阅读(803)  评论(0编辑  收藏

导航