08-了解各种不同意义的new和delete
第二章,操作符
条款8 了解各种不同意义的new和delete
区分new operator与operator new
new operator是C++内建的,其行为有两个,一是隐式调用operator new分配足够的内存空间,二是调用构造函数返回对象给指针。
//编写的代码: |
在重载new操作符时,实际是重载operator new,无法直接调用构造函数来完成new operator的第二个行为; operator new必须要有一个size_t自变量参数。
Placement new
要实现在已经分配好的内存上调用构造函数,可以使用placemen new,这是new operator的一种用法。
|
在new之后加上一个额外的自变量(buffer),当new operator(语言内建)隐式调用operator new时,指定在这块内存上构造对象;这里的operator new 除了接收widgetSize还接收了一个void*参数,就像这样:
void * operator new(size_t,void *location) |
operator new的目的就是为对象找到一块内存,然后返回指向这块内存的指针。
注意,要使用plcaement new必须包含头文件new.h
删除与内存释放
内建的delete operator与operator delete和new operator与operator new的关系同样是前者隐式调用后者。
string *ps; |
编译器在解析上面的代码时会生成对应的代码,确保既能够析构ps所指向的对象,又能够释放该对象占用的内存。其中内存释放动作是由函数operator delete执行的,通常声明如下:
void operator delete(void *memoryToBeDeallocated); |
因此 delete ps;会让编译器产生如下代码:
ps->~string(); //调用对象的析构函数 |
回顾总结并强调
(1)打算处理原始未设初值的内存,应该完全回避new operator和delete operator(实际就是new与delete),而是改调用 operator new 和 operator delete(这是实际可写的代码,不是称谓); 这组行为在C++中相当于调用malloc与free;
(2)当使用Placement new在某内存中产生对象,应该避免对该内存使用delete operator, 因为这块内存不是由operator new分配得来的。Placement new只是返回它所接收的指针,但指针从何而来无人知晓。所以为了抵消改对象的构造函数的影响,应该直接调用该对象的析构函数:
|
数组
string *ps = new string[10]; //分配一个对象数组 |
上述使用的仍然是new operator,但是隐式调用的不再是operator new,而是operator new[]; 数组版的new operator会针对数组中的每一个对象调用构造函数,数组版的delete operator也会针对数组中的每一个对象调用析构函数。
operator new[]和operator delete[]都可以操作符重载
