C++ placement new 用法举例

在处理内存分配的时候, C++ 程序员会用 new 操作符( operator new )来分配内存,并用 delete 操作符( operator delete )来释放内存。这是一个 new 操作符的例子。

class CTest
{
      /* 成员函数和成员数据 */
};

// . . . 代码

// 分配一个对象
CTest * pTest = new Test;
// 分配一个有十个对象的数组 (CTest 要有缺省构造函数( default constuctor ) )
CTest * p10Tests = new Test[ 10];

虽然这种写法在大多数时候都工作得很好,但还是有些情况下使用 new 是很烦人的,比如当你想重新分配一个数组或者当你想在预分配的内存上构造一个对象的时候。

比如第一种情况,重新分配一个数组效率是很低的:

// 分配一个有 10 个对象的数组
CTest * pTests = new Test[ 10];
// . . .
// 假设现在我们需要 11 个对象
CTest * pNewTests = new Test[ 11];
// . . . 我们必须把原来的对象拷贝到新分配的内存中
for ( int i = 0; i < 10; i++)
     pNewTests[ i] = pTests[ i];
delete pTests;
pTests = pNewTests;

如果你想在预分配的内存上创建对象,用缺省的 new 操作符是行不通的。要解决这个问题,你可以用 placement new 构造。它允许你构造一个新对象到预分配的内存上:

// buffer 是一个 void 指针 (void *)
// 用方括号 [] 括起来的部分是可选的
[CYourClass * pValue = ] new( buffer) CYourClass[( parameters)];

下面是一些例子:

#include <new>

class CTest
{
public:
     CTest()
     {}
     CTest( int)
     {}
     /* 代码 */
};

int main(int argc, char* argv[])
{
     // 由于这个例子的目的,我们不考虑内存对齐问题
     char strBuff[ sizeof( CTest) * 10 + 100];
     CTest * pBuffer = ( CTest *)strBuff;

     // 缺省构造
     CTest * pFirst = new(pBuffer) CTest;

     // 缺省构造
     CTest * pSecond = new(pBuffer + 1) CTest;
    
     // 带参数的构造;
     // 不理会返回的指针
     new(pBuffer + 2) CTest( 5);

     // 带参数的构造
     CTest * pFourth = new( pBuffer + 3) CTest( 10);

     // 缺省构造
     CTest * pFifth = new(pBuffer + 4) CTest();

     // 构造多个元素(缺省构造)
     CTest * pMultipleElements = new(pBuffer + 5) CTest[ 5];
     return 0;
}

当你有自己的内存缓冲区或者在你实现自己的内存分配策略的时候, placement new 会很有用。事实上在 STL 中广泛使用了 placement new 来给容器分配内存;每个容器类都有一个模版参数说明了构造 / 析构对象时所用的分配器( allocator )。

在使用 placement new 的时候,你要记住以下几点:

  • 加上头文件 #include <new>
  • 你可以用 placement new 构造一个数组中的元素。
  • 要析构一个用 placement new 分配的对象,你应该手工调用析构函数(并不存在一个 “placement delete” )。它的语法如下:

pFirst->~CTest();
pSecond->~CTest();

 

http://hi.baidu.com/dongkundjy/blog/item/71cd21fb3c9c66294f4aeaa8.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值