虽然有三种new的用法,但是分为两大类也未尝不可,那么是哪两类呢?其一是new operator,也叫new表达式;其二是operator new,也叫new操作符。这两个英文名称起的也太绝了,很容易搞混,那就记中文名称吧。new表达式比较常见,也最常用,例如:
string*ps=new string("abc");
上面这个new表达式完成了两件事情:申请内存和初始化对象。
new操作符类似于C语言中的malloc,只是负责申请内存,例如:
void*buffer=operator new(sizeof(string));
注意这里多了一个operator。这是new的第二个用法,也算比较常见吧。
那么第三个用法就不很常见了,官方的说法是placement new,它用于在给定的内存中初始化对象,也就是说你手中已有一块闲置的内存,例如:
void*buffer=operator new(sizeof(string));
//那么现在buffer是你所拥有闲置内存的指针
buffer=new(buffer)string("abc");//调用了placement new,在buffer所指向的内存中初始化string类型的对象,初始值是"abc"
事实上,placement new也是new表达式的一种,但是比普通的new表达式多了一个参数,当然完成的操作和返回值也不同。
因此上面new的第一种用法可以分解两个动作,分别为后面的两种用法。
与new对应的delete没有三种语法,它只有两种,分别是delete operator和operator delete,也称为delete表达式和delete操作符。delete表达式和new表达式对应,完成对象的析构
和内存的释放操作。而delete操作符只是用于内存的释放,和C语言中的free相似。例如:string*ps=new string("abc");
...
delete ps;//调用delete表达式,先析构再释放
void*buffer=operator new(sizeof(string));
...
operator delete(buffer);//释放
那么为什么没有和placement new对应的那个delete呢?其实是有的。placement new是在指定位置初始化对象,也就是调用了构造函数,因此与之对应的就是析构函数了,只不过它不叫placement delete而已。
void*pv=operator new(sizeof(vector<int>));
pv=new(pv)vector<int>(8,0);
...
static_cast<vector<int>*>(pv)->~vector();//call destruct function
operator delete(pv);//free memory
pv=NULL;
[注]参考自more effective C++
另:operator new会多申请sizeof(int)大小的内存用来保存这段空间的大小。
placement new如果在申请一个数据的时候也要多申请sizeof(int)大小的空间用来保存数组的大小。eg,
void*ptr=operatro new(sizeof(int)*100);
int*iPtr=new(ptr)int[100];//如果这样,那么这里将会出错的,因为你实际上系统是申请了100+sizeof(int)的空间!然而ptr上面只有100*szieof(int)的大小,所以申请空间失败。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论