2008年(909)
分类:
2008-05-06 21:37:33
赵湘宁
常常有人问这样一个C 问题:如何在预先定义的内存位置构造一个对象?在预先定义的内存缓冲构造一个对象有许多有用的应用。例如,一个定制的垃圾搜集器能使用一个大的预分配内存缓冲,用户在这个缓冲中构造其对象。当不再需要这些对象时,它们的存储空间被自动收回。char * buff = new char [sizeof (Foo) ];一旦分配了缓冲,就能在缓冲中构造每一种类型的对象。为此,使用特殊版本的new操作符(“定位new”),以缓冲地址为placement new的参数。为了使用placement new,必须包含标准头文件
#includePlacement new 以先前分配的缓冲(buff)地址作为参数,并在这个缓冲上构造给定类型的对象。他返回构造对象的指针,这个对象指针的使用与通常的指针使用没什么两样。Foo * pfoo = new (buff) Foo; //使用new操作在buff上构造一个 Foo
unsigned int length = pfoo->size(); pfoo->resize(100, 200); length = pfoo->size();当不再需要这个对象的时候,必须显式调用其析构函数释放空间。做这件事是有一些技巧的,因为许多人错误地假设对象会被自动销毁,错也!。在预分配的缓冲里构造另一个对象之前或者在释放缓冲之前,如果忘了显式调用析构函数,程序将产生不可预料的后果。显式的析构器声明如下:
pfoo->~Foo(); //显式调用析构函数换句话说,一个显式的析构器与普通的成员函数调用一样,只是名字与普通的成员函数稍有差别。一旦对象被销毁,便可以在预分配的内存中再次构造另一个对象。实际上,这个过程可以无限制地重复:构造一个对象,销毁它,然后又反复利用预分配的缓冲构造新对象。
#include下载本文示例代码void placement_demo() { //1. 预分配缓冲 char * buff = new char [sizeof (Foo) ]; //2. 使用 placement new Foo * pfoo = new (buff) Foo; //使用对象 unsigned int length = pfoo->size(); pfoo->resize(100, 200); //3. 显式调用析构函数 pfoo->~Foo(); //4. 释放预定义的缓冲 delete [] buff; }