More Effective C++ 读书笔记三

条款8:了解各种不同意义的new和delete

这里讲了3种new,分别是:new operator, operator new, placement new。

new operator最简单,它就是我们平时常用的new关键字,需要注意的是,它是不能被重载的。new operator的语义是先分配内存,然后调用对象的构造函数。

operator new:这个是这三个new里面唯一能够重载的,平时我们重载的就是这个操作符。它的声明是:

[cc lang="cpp"]
void *operator new(size_t size);
[/cc]

但是operator new即使重载了,也只能负责分配内存,没法完成new operator的后面那步:指定构造函数。

placement new:我们没法直接在代码中调用构造函数,placement new的作用,就是在给定的内存上构造对象。也就是完成了new operator的第二步。用的最多的可能就是在已经申请的共享内存上构造对象。

也就是说:new operator = operator new + placement new

摘录下总结:“如果你希望将对象产生于heap,请使用new operator。它不但分配内存而且为该对象调用一个constructor。如果你只是打算分配内存,请调用operator new,那就没有任何constructor会被调用。如果你打算在heap objects产生时自己决定内存分配方式,请写一个自己的operator new。如果你打算在已分配(并拥有指针)的内存中构造对象,请使用placement new。”

 

delete没有这么复杂,只有两个:delete operator和operator delete

看了前面的解释,这个就简单多了,delete operator是c++内置的不能修改,所做的事情,就是执行析构函数,并释放内存。

operator delete是能够重载的,一般会和operator new一起重载,以自定义内存的释放方式。

delete operator = deconstructor + operator delete

 

用代码来总结下前面提到的:

[cce lang="cpp"]
#include <new>
#include <iostream>

class Obj
{
public:
Obj(int a) : _a(a){}
~Obj(){std::cout<<"die"<<std::endl;}
int _a;
};

int main()
{
void *rawMem = operator new(sizeof(Obj)); //operator new
Obj *obj = new(rawMem) Obj(10); //placement new
std::cout << obj->_a << std::endl; //对象构造完毕
//和Obj *obj = new Obj(10)相同

obj->~Obj(); //deconstructor
operator delete (obj); //operator delete
//对象销毁完毕,和delete obj相同
return 0;
}
[/cce]

最后简单说下数组,c++分配数组和删除数组,需要加一个[],这是因为执行类似string *p = new string[10];的时候,new operator会去调用operator new[],删除的时候必须使用delete [] p;同样是因为,需要让delete operator能够正确的调用operator delete[]。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据