这里有人用过c++的“placement new”吗?如果有,为什么?在我看来,它只在内存映射硬件上有用。
当前回答
如果你想把分配和初始化分开,这是很有用的。STL使用放置new来创建容器元素。
其他回答
Head Geek: BINGO! You got it totally - that's exactly what it's perfect for. In many embedded environments, external constraints and/or the overall use scenario forces the programmer to separate the allocation of an object from its initialization. Lumped together, C++ calls this "instantiation"; but whenever the constructor's action must be explicitly invoked WITHOUT dynamic or automatic allocation, placement new is the way to do it. It's also the perfect way to locate a global C++ object that is pinned to the address of a hardware component (memory-mapped I/O), or for any static object that, for whatever reason, must reside at a fixed address.
我使用它来创建基于内存的对象,其中包含从网络接收到的消息。
这里是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
它可能在使用共享内存时很方便,在其他用途中…例如:http://www.boost.org/doc/libs/1_51_0/doc/html/interprocess/synchronization_mechanisms.html#interprocess.synchronization_mechanisms.conditions.conditions_anonymous_example
我们将它用于自定义内存池。简单介绍一下:
class Pool {
public:
Pool() { /* implementation details irrelevant */ };
virtual ~Pool() { /* ditto */ };
virtual void *allocate(size_t);
virtual void deallocate(void *);
static Pool *Pool::misc_pool() { return misc_pool_p; /* global MiscPool for general use */ }
};
class ClusterPool : public Pool { /* ... */ };
class FastPool : public Pool { /* ... */ };
class MapPool : public Pool { /* ... */ };
class MiscPool : public Pool { /* ... */ };
// elsewhere...
void *pnew_new(size_t size)
{
return Pool::misc_pool()->allocate(size);
}
void *pnew_new(size_t size, Pool *pool_p)
{
if (!pool_p) {
return Pool::misc_pool()->allocate(size);
}
else {
return pool_p->allocate(size);
}
}
void pnew_delete(void *p)
{
Pool *hp = Pool::find_pool(p);
// note: if p == 0, then Pool::find_pool(p) will return 0.
if (hp) {
hp->deallocate(p);
}
}
// elsewhere...
class Obj {
public:
// misc ctors, dtors, etc.
// just a sampling of new/del operators
void *operator new(size_t s) { return pnew_new(s); }
void *operator new(size_t s, Pool *hp) { return pnew_new(s, hp); }
void operator delete(void *dp) { pnew_delete(dp); }
void operator delete(void *dp, Pool*) { pnew_delete(dp); }
void *operator new[](size_t s) { return pnew_new(s); }
void *operator new[](size_t s, Pool* hp) { return pnew_new(s, hp); }
void operator delete[](void *dp) { pnew_delete(dp); }
void operator delete[](void *dp, Pool*) { pnew_delete(dp); }
};
// elsewhere...
ClusterPool *cp = new ClusterPool(arg1, arg2, ...);
Obj *new_obj = new (cp) Obj(arg_a, arg_b, ...);
现在你可以将对象聚集在一个单独的内存区域中,选择一个非常快但不进行释放的分配器,使用内存映射,以及任何你希望通过选择池并将其作为参数传递给对象的放置new操作符来施加的语义。
推荐文章
- decltype(auto)的一些用途是什么?
- Shared_ptr转换为数组:应该使用它吗?
- Printf与std::字符串?
- 禁用复制构造函数
- 只接受特定类型的c++模板
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 为什么ARC仍然需要@autoreleasepool ?
- c++ 11中的递归lambda函数
- 在c++中指针使用NULL或0(零)吗?
- 在c++中,如何将int值附加到字符串中?
- 就性能而言,使用std::memcpy()还是std::copy()更好?
- 为什么布尔值是1字节而不是1位?
- 四舍五入到一个数字的最接近倍数
- 模板默认参数
- c++ auto关键字。为什么它是魔法?