/*
*C++ 语言学习
* —— placement 语法
* 内容来自网上及摘自 C++ Strategies and Tactics
*/
Placement New
关键字new能够接受参数:
p = new(arg1, arg2, arg3) D;
这些参数会被隐含地传给new操做函数:
p = operator new(sizeof(D), arg1, arg2, arg3);
注意,第一个参数仍然是要生成对象的字节数,其它参数老是跟在它后面。
标准运行库定义了一个new操做的特别重载版本,它接受一个额外参数:
void * operator new(std::size_t, void *);
这种形式的new操做被以下的语句隐含调用:
p = new(addr) D;
这里,addr是某些数据区的地址,而且类型兼容于void *。addr传给这个特别的new操做,这个特别的new操做和其它new操做同样返回将被构造的内存的地址,但不须要在自由内存区中再申请内存,它直接将addr返回:
void *operator new(std::size_t, void *addr)
{
return addr;
}
这个返回值而后被传给D::D做构造函数的this指针。
就这样,表达式:
p = new(addr) D;
在addr所指的内存上构造了一个D对象,并将p赋为addr的值。这个方法让你有效地指定新生成对象的位置,因此被叫做“placement new”。
这个new的额外参数形式最初被设计为控制对象的位置的,可是C++标准委员会认识到这样的传参体系能够被用于任意用途而不只是控制对象的位置。不幸的是,术语“placement”已经被根据最初目的而制订,并适用于全部new操做的额外参数的形式,即便它们根本不试图控制对象的位置。
因此,下面每一个表达式都是placement new的一个例子:
new(addr) D; // calls operator new(std::size_t, void *)
new(addr, 3) D; // calls operator new(std::size_t, void *, int)
new(3) D; // calls operator new(std::size_t, int)
即便只有第一个形式是通常被用做控制对象位置的。
placement Delete
如今,只要认为 placement delete 是有用处的就好了。我确定会讲述理由的,可能就在接下来的两篇内。
Placement new操做和placement delete操做必须成对出现。
通常来讲,每个
void *operator new(std::size_t, p1, p2, p3, ..., pN);
都对应一个
void operator delete(void *, p1, p2, p3, ..., pN);
根据这条原则,标准运行库定义了
void operator delete(void *, void *);
以对应我刚讲的placement new操做。
数组New和数组Delete
基于对称,标准运行库也申明了placement new[]操做和placement delete[]操做:
void *operator new[](std::size_t, void *);
void operator delete[](void *, void *);
如你所料:placement new[]操做返回传入的地址,而placement delete[]操做的行为和我没有细述的placement delete操做行为几乎同样。 数组
下面摘自《C++ Strategies and Tactics》 函数
经过在紧接着 new 关键字后使用括号列表,用户能够向 operator new 传递参数: