首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这些放置新宏是正确的吗?

这些放置新宏是正确的吗?
EN

Stack Overflow用户
提问于 2009-10-16 23:57:06
回答 5查看 615关注 0票数 2

我做了几个宏,以使使用新的放置更容易一些。我只是想知道是否有任何明显的情况下,这些都不起作用。谢谢。

代码语言:javascript
复制
#define CONSTRUCT_INPLACE(TYPE,STORAGE,INIT)   ::new((TYPE*)STORAGE) TYPE INIT
#define DESTRUCT_INPLACE(TYPE,STORAGE)         ((TYPE*)STORAGE)->~TYPE()
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-10-17 00:06:21

我不是放置新的方面的专家,但是关于如何定义宏有几个问题。

问题1

最明显的问题是使用cast (TYPE*)STORAGE作为存储位置。这是不正确的。Placement new只是另一个C++函数,它参与重载解析等操作。将内存任意转换为特定类型可能会导致放置new绑定到用户预期的不同运算符new。

例如,具有以下两个放置新的定义是有效的。您的宏有可能导致调用错误的宏。

代码语言:javascript
复制
void * _cdecl operator new(size_t cbSize, void* pv);
void * _cdecl operator new(size_t cbSize, SomeType* pv)-

..。

代码语言:javascript
复制
// These two call different overloads
void* p = malloc(sizeof(SomeType));
SomeType* f1 = CONSTRUCT_INPLACE(SomeType, p,()) 
SomeType* f2 = new (p) SomeType();

不久前,我写了一篇博客文章,介绍如何使用这种类型的重载解析来实现自定义分配器。

  • http://blogs.msdn.com/jaredpar/archive/2007/10/17/c-placement-new-and-allocators.aspx

第2期

宏中的表达式存储应该包含在括号中,以防止恶意的宏扩展错误。

代码语言:javascript
复制
::new((TYPE*)(STORAGE)) TYPE INIT
票数 6
EN

Stack Overflow用户

发布于 2009-10-17 00:16:33

除了其他地方提到的问题之外,你的宏与模板类型的交互非常糟糕(例如,无法编译)。

一般来说,当没有明确的好处时,应该避免使用宏。坦率地说,我看不出这有什么好处。

例如:

代码语言:javascript
复制
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;
}
票数 2
EN

Stack Overflow用户

发布于 2009-10-17 00:02:52

看着他们,我想知道(TYPE*)的第一个演员阵容是为了什么-毕竟,放置新的void*

但话又说回来,我想知道它们到底有什么好处。他们所做的一切就是进一步混淆一些本来就不是很微不足道的东西。你为什么认为你需要他们?

话虽如此,您是否看过(诚然为数不多)用于处理未初始化内存的标准库工具?(参见this网站的下半部分。也许你可以用到一些东西。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1580960

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档