定位new表达式

1.经典例子

#include <iostream>
#include <new>
const intchunk = 16;
class Foo
{
public :
	int val( ) { return _val; }
	Foo( ) { _val = 0; }
private :
	int_val;
};

//预分配内存,但没有Foo对象
char*buf = new char[ sizeof(Foo) * chunk ];
int main( void )
{
	//在buf中创建一个Foo对象
	Foo*pb = new (buf) Foo;
	//检查一个对象是否被放在buf中
	if ( pb->val() == 0 )
	{
		cout <<"new expressio worked!" <<endl;
	}
	//到这里不能再使用pb
	delete[] buf;
	return 0;
}

这种“定位new表达式”相对于一般的new的优点是什么?它的用法比一般的new对象要复杂!


2.使用定位new表达式作用
  1)placement new的作用就是:创建对象但是不分配内存,而是在已有的内存块上面创建对象。用于需要反复  创建并删除的对象上,可以降低分配释放内存的性能消耗。
  2)定位new表达式(placement new expression,C++ primer P347),允许程序员将对象创建在已经被分配好的内存中,new表的式的形式如下:
 
new (place_address) type
new (palce_address) type (initializer-list)
 
place_address必须是个指针,指向已经分配好的内存。为了使用这种形式的new表达式,必须包含头文件<new>。
 
 
定位new表达式不能调用delete删除 placement new的对象,需要人为的调用对象的析构函数,并且人为的释放掉占用的内存。

#include <iostream> 
#include <new> 

using namespace std; 

const int chunk = 16; 

class Foo 
{ 
public: 
	int val(){return _val;} 
	Foo(){_val=0;} 
private: 
	int _val; 
}; 

int main() 
{ 
	// 预分配内存buf 
	char *buf = new char[sizeof(Foo) * chunk]; 

	// 在buf中创建一个Foo对象
	Foo *pb=new (buf) Foo; 
	// 检查一个对象是否被放在buf中
	if(pb->val()==0) cout<<"new expression worked!"<<endl; 
	// 这里不存在与定位new表达式匹配的delete表达式,即:delete pb, 其实只是为了
	// 释放内存的话,我们不需要这样的表达式,因为定位new表达式并不分配内存。
	// 如果在析构函数中要做一些其他的操作呢?就要显示的调用析构函数。
	// 当程序不再需要buf时,buf指向的内存被删除,它所包含的任何对象的生命期也就
	// 都结束了。 

	delete[] buf; 
	return 0; 
}

定位new表达式的应用:
 
在我们的程序中,首先使用malloc为对象分配空间,然后通过定位new表达式将对象创建在已经被分配好的内存中,完成构造函数的调用。
    3)
“new (start) Screen;”   这是定位new操作
 Screen *ps = new (start) Screen;   表示在已经开辟好的内存区start中为堆对象Screen申请一个内存

  也就是说,如果start占100个字节,你现在从它的第1个字节开始,往里面写入Screen,这样做今后要释放内存的时候有麻烦,如果Screen里面有指针,并开辟了空间,那么delete ps会调用析构函 数,然而在释放指针变量所占的内存空间时也释放了为对象所分配的内存空间,所以start中的那块内存也丢失了,因为ps也指向了start.所以要避免这种情况,就要先ps->~Screen()这样显示的调用Screen的析构函数,再delete []start。


【摘自:http://blog.sina.com.cn/s/blog_60e96a410100mqpn.html】


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值