总结C++中三种关于”new”的使用方法

来源:互联网 发布:mac dock栏屏幕切换 编辑:程序博客网 时间:2024/06/01 08:48

http://brightli.wordpress.com/2007/03/29/%E6%80%BB%E7%BB%93c%E4%B8%AD%E4%B8%89%E7%A7%8D%E5%85%B3%E4%BA%8Enew%E7%9A%84%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95/

 

虽然有三种new的用法,但是分为两大类也未尝不可,那么是哪两类呢?

其一是new operator,也叫new表达式;

其二是operator new,也叫new操作符。

其三是placement new, 我觉的就是operator new的overload

这两个英文名称起的也太绝了,很容易搞混,那就记中文名称吧。

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++

 

一个网上的例子,

#include <iostream>
using namespace std;

// operator new example
#include <iostream>
#include <new>
using namespace std;

class myclass
{
public:
    myclass() {cout <<"myclass constructed/n";}
    ~myclass(){cout <<"myclass destructed/n";}
};

int main () {

   int * p1 = new int;
// same as:
// int * p1 = (int*) operator new (sizeof(int));

   int * p2 = new (nothrow) int;
// same as:
// int * p2 = (int*) operator new (sizeof(int),nothrow);

   myclass * p3 = (myclass*) operator new (sizeof(myclass));
// (!) not the same as:
// myclass * p3 = new myclass;
// (constructor not called by function call, even for non-POD types)

   new (p3) myclass;   // calls constructor
// same as: the same as?, constructor is not called
// operator new (sizeof(myclass),p3);

   delete p3;
// same as:
//   p3->~myclass();
//   operator delete(p3);

//   myclass obj;
   myclass *pobj = new myclass;
   pobj->~myclass();
   return 0;
}

 

 

原创粉丝点击