现在的位置: 首页 > 综合 > 正文

Placement new 在MFC工程下的尴尬

2012年10月28日 ⁄ 综合 ⁄ 共 888字 ⁄ 字号 评论关闭

这几天因为要使用AngleScript,对C++又有了一些新的认知。比如.placement new

简单介绍一下,其实这个new是一个全局的,不可被覆盖的new操作符。它的作用是重新构造已有对象。重新构造,而不是重新分配,所以只可以作用在已经被分配的内存空间上。这也正是“placement”的含义

比如int * p = new int[5];

new(p) int[5];

这样做是合法的。

int * p;

new(p) int [5]; //会出现执行期错误。因为p并没有事先被分配。

其实,placement new就是重新调用对象的构造函数。

小弟才疏学浅,也是最近几天才刚刚了解到这个操作符的,最开始是看到网上一些Anglescript 的simple上用这个操作符来构造对象。一开始也不明白它的意思,只是copy 到自己的工程下。但无法编译通过,当时也没在意,以为就是个从heap创建对象的动作呢,于是就用p = new obj();代替。不过很快就反应过来,这样是行不通的,因为p在这个语句中会指向一个重新分配的空间。而script已经替p分配了空间,只是用新的参数重新构造它而已。

但为什么编译不过呢,google了一下也没找到答案。于是新建了一个普通的控制台程序。一样的语句编译通过,看来不是编译器的问题。对照了两个工程的编译器选项,也没什么本质差别。奇怪。

尝试性的查看<new>头文件,发现里面有个条件编译 

#ifndef __PLACEMENT_NEW_INLINE

难道我没有定义它?

定义之后,提示afxtempl.h编译错误。

定位到错误处,答案就这样被有心人发现了

#pragma push_macro("new")
#undef new
 ::new( (void*)( &pNode->data ) ) TYPE;
#pragma pop_macro("new")

该死的,他们也不通知我一声,太狠了。

又回到<new>里面,发现文件最下面还有这样两行定义

#ifdef  _MSC_VER
  #pragma pop_macro
("new")

NND,被他们搞死了。不过总算是能用了。拿出来和大家分享一下,也许哪天你也会遇到类似的问题

抱歉!评论已关闭.