我做了几个宏,以使使用新的放置更容易一些。我只是想知道是否有任何明显的情况下,这些都不起作用。谢谢。
#define CONSTRUCT_INPLACE(TYPE,STORAGE,INIT) ::new((TYPE*)STORAGE) TYPE INIT
#define DESTRUCT_INPLACE(TYPE,STORAGE) ((TYPE*)STORAGE)->~TYPE()发布于 2009-10-17 00:06:21
我不是放置新的方面的专家,但是关于如何定义宏有几个问题。
问题1
最明显的问题是使用cast (TYPE*)STORAGE作为存储位置。这是不正确的。Placement new只是另一个C++函数,它参与重载解析等操作。将内存任意转换为特定类型可能会导致放置new绑定到用户预期的不同运算符new。
例如,具有以下两个放置新的定义是有效的。您的宏有可能导致调用错误的宏。
void * _cdecl operator new(size_t cbSize, void* pv);
void * _cdecl operator new(size_t cbSize, SomeType* pv)-..。
// These two call different overloads
void* p = malloc(sizeof(SomeType));
SomeType* f1 = CONSTRUCT_INPLACE(SomeType, p,())
SomeType* f2 = new (p) SomeType();不久前,我写了一篇博客文章,介绍如何使用这种类型的重载解析来实现自定义分配器。
第2期
宏中的表达式存储应该包含在括号中,以防止恶意的宏扩展错误。
::new((TYPE*)(STORAGE)) TYPE INIT发布于 2009-10-17 00:16:33
除了其他地方提到的问题之外,你的宏与模板类型的交互非常糟糕(例如,无法编译)。
一般来说,当没有明确的好处时,应该避免使用宏。坦率地说,我看不出这有什么好处。
例如:
template< class A, class B >
class T
{
public:
T(A y, B z) : x(y), w(z) {}
A x;
B w;
};
int main()
{
void* p = ::operator new(sizeof(T));
CONSTRUCT_INPLACE(T<int, double>, p, (4, 5.0));
DESTRUCT_INPLACE(T<int, double>, p);
::operator delete(p);
return 0;
}发布于 2009-10-17 00:02:52
看着他们,我想知道(TYPE*)的第一个演员阵容是为了什么-毕竟,放置新的void*。
但话又说回来,我想知道它们到底有什么好处。他们所做的一切就是进一步混淆一些本来就不是很微不足道的东西。你为什么认为你需要他们?
话虽如此,您是否看过(诚然为数不多)用于处理未初始化内存的标准库工具?(参见this网站的下半部分。也许你可以用到一些东西。
https://stackoverflow.com/questions/1580960
复制相似问题