C++中的new和delete——读书笔记小结

C++中的new和delete——读书笔记总结

时间:2014.03.12

地点:基地

------------------------------------------------------------------------------

一、简述

  先看这样的代码:

string* ps=new string("HuNanUniversity");
这是new operator的用法,它的包含两个动作,一是分配足够的内存,用来放置类型对象。比如上述它会分配一个足够放置string对象的内存块出来;二是调用构造函数,为刚刚分配的内存中的对象设定初值。人们常说的new一个东西出来,即总是做这两件事。但可以改变内存的分配行为,只要重载操作符new就OK。

------------------------------------------------------------------------------

二、new对象时的实质

函数operator new通常这样声明:

void* operator new(size_t size);
返回值类型是void* ,是一个指针,指向一块最原始的、未初始化的内存。size表示需要分配多少内存。我们甚至可以像其他函数一样调用它,比如:

void* rawMemory=operator  new(sizeof(string));
这里operator new会返回一个指针,指向一块足够容纳一个string对象的内存。和malloc一样,operator new的唯一任务就是分配内存,而将内存转换为一个存有内容的对象是new operator的责任。比如上述第一个段代码,表面上我们只new了对象,未涉及内存分配,但这样一个语句会产生如下代码:

void* memory=operator new(sizeof(string));//取得原始内存,用来放置一个string对象
call  string::string("HuNanUniversity") on *memory; //将内存中的对象初始化
string *ps=static_cast<string*)(memory);  //将指针类型做转换,让ps指向新完成的对象

------------------------------------------------------------------------------

三、placement new

  有时当你得到一块原始内存,你想在上面构建对象时需要用到placement new,程序员直接调用构造函数是不被许可的。比如:

class Widget{
public:
  Widget(int widgetSize);
  ...
};
Widget* constructWidgetInBuffer(void* buffer,int widgetSize){
  return new (buffer) Widget(widgetSize);
}
上面的constructWidgetInBuffer函数返回一个指针,指向Widget object,它被构造于传递给函数的一块内存缓冲区上,即buffer指向的原始内存块上。有些应用对象必须置于特定的地址,那么现在placement new就有用了。

一下解释 new(buffer) Widget(widgetSize)

这是new operator的用法之一,额外的变量buffer将作为new operator隐式调用operator new所用。此时operator new除了接受 size-t自变量之外还接受一个void*参数,指向一块内存,准备用来接受在这之上构建的对象,即这里的buffer。看起来就是这样;

void* operator new(size_t,void* location){
  return location;
}
operator new的目的就是要为对象找到一块内存,然后返回一个指针指向该内存。在placement new场景下,因为已经知道目的内存了,不需要再去寻找了,如此简单返回这块内存即可,placement new要做的就是将他自己获得的指针再次返回。
------------------------------------------------------------------------------

四、总结

  如果你希望将对象产生于堆上,使用new operator,比如:new int(20); new string("ChangSha");它实际上是执行分配内存和自动调用构造函数在内存上构建对象。如果只打算分配内存,调用operator new即可获得原始内存分配,还可以写自己的operator new决定内存分配方式,这时使用new operator时会自动调用你写得operator new分配内存。要是打算在你已分配的内存中构建对象,使用placement new即可。