代码之家  ›  专栏  ›  技术社区  ›  Adisak

这些新宏的位置正确吗?

  •  2
  • Adisak  · 技术社区  · 17 年前

    #define CONSTRUCT_INPLACE(TYPE,STORAGE,INIT)   ::new((TYPE*)STORAGE) TYPE INIT
    #define DESTRUCT_INPLACE(TYPE,STORAGE)         ((TYPE*)STORAGE)->~TYPE()
    
    5 回复  |  直到 17 年前
        1
  •  6
  •   JaredPar    17 年前

    我不是一个新的布局专家,但在如何定义宏方面有几个问题。

    最明显的问题是铸件的使用 (TYPE*)STORAGE

    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
    
        2
  •  2
  •   CB Bailey    17 年前

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

    例如

    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;
    }
    
        3
  •  1
  •   sbi    14 年前

    看着他们,我想知道这是怎么回事 (TYPE*) void* 毕竟。

    但话说回来,我想知道它们到底有什么好处。他们所能做的只是进一步混淆一些原本并不琐碎的事情。你为什么认为你需要它们?

    话虽如此,您是否看过(公认为少数)用于处理未初始化内存的标准库设施(见下半部分 this 网站。也许有一些东西你可以用。

        4
  •  0
  •   David Seiler    17 年前

    你的 CONSTRUCT_INPLACE 我觉得有点奇怪。用途如下:

    void* p = <some memory location>;
    Foo* f = CONSTRUCT_INPLACE(Foo, p, Foo())
    
    // The macro-free version seems easier to read:
    Foo* f = new(p) Foo();
    

    DESTRUCT_INPLACE 至少比它替换的代码更容易阅读。

    但真的,为什么你要做这么多新的放置,这些宏对你有用?把那些东西放在台球课上,忘掉它。

        5
  •  0
  •   AnT stands with Russia    17 年前

    顺便问一下,拥有这些宏有什么意义?你说他们“让使用新的位置变得更容易”,但他们似乎只是执行一些完全不必要的强制转换。