这里有人用过c++的“placement new”吗?如果有,为什么?在我看来,它只在内存映射硬件上有用。


当前回答

这里是c++ in-place构造函数的杀手级用法:对齐缓存线,以及其他2边界的幂。以下是我的超快速指针对齐算法,使用5个或更少的单周期指令,达到2边界的任意幂:

/* Quickly aligns the given pointer to a power of two boundary IN BYTES.
@return An aligned pointer of typename T.
@brief Algorithm is a 2's compliment trick that works by masking off
the desired number in 2's compliment and adding them to the
pointer.
@param pointer The pointer to align.
@param boundary_byte_count The boundary byte count that must be an even
power of 2.
@warning Function does not check if the boundary is a power of 2! */
template <typename T = char>
inline T* AlignUp(void* pointer, uintptr_t boundary_byte_count) {
  uintptr_t value = reinterpret_cast<uintptr_t>(pointer);
  value += (((~value) + 1) & (boundary_byte_count - 1));
  return reinterpret_cast<T*>(value);
}

struct Foo { Foo () {} };
char buffer[sizeof (Foo) + 64];
Foo* foo = new (AlignUp<Foo> (buffer, 64)) Foo ();

这是不是让你的脸上露出了微笑(:)。我♥♥♥c++ 1x

其他回答

如果你想把分配和初始化分开,这是很有用的。STL使用放置new来创建容器元素。

在http://xll.codeplex.com上查看xll项目中的fp.h文件,它解决了喜欢随身携带维度的数组“与编译器的不必要的亲密关系”问题。

typedef struct _FP
{
    unsigned short int rows;
    unsigned short int columns;
    double array[1];        /* Actually, array[rows][columns] */
} FP;

在序列化时(比如使用boost::serialization),放置new也非常有用。在c++的10年里,这只是我第二次需要新职位的情况(如果你包括面试的话,这是第三次:))。

当您想重新初始化全局或静态分配的结构时,它也很有用。

旧的C方法是使用memset()将所有元素设置为0。在c++中,由于虚函数和自定义对象构造函数,无法做到这一点。

所以我有时会用下面的方法

 static Mystruct m;

 for(...)  {
     // re-initialize the structure. Note the use of placement new
     // and the extra parenthesis after Mystruct to force initialization.
     new (&m) Mystruct();

     // do-some work that modifies m's content.
 }

我使用它来创建基于内存的对象,其中包含从网络接收到的消息。