【问题标题】:rvalue references with placement new (similar functionality to std::vector.push_back)带有新位置的右值引用(类似于 std::vector.push_back 的功能)
【发布时间】:2015-11-30 01:24:56
【问题描述】:

我正在实现一个容器类 (ObjectPool)。它在连续内存中维护一个模板对象数组。在构造时,它分配一块内存(相当于(模板对象的大小)*(池大小))。向池中添加新对象时,它使用“placement new”运算符在特定内存地址创建对象(并自动调用模板对象的构造函数)。

如何实现 ObjectPool.add() 方法,以接受模板对象并将其添加到对象池,而不调用它的构造函数两次(例如在 std::vector.push_back() 中实现的功能)?

为简单起见,在这种情况下,ObjectPool 类只包含一个模板对象,而不是一个数组。

class FooClass
{
public:
    FooClass(int p_testValue) : m_testValue(p_testValue)
    {
        std::cout << "Calling constructor: " << m_testValue << std::endl;
    }

    int m_testValue;
};

template <class T_Object>
class ObjectPool
{
public:
    ObjectPool()
    {
        // Allocate memory without initializing (i.e. without calling constructor)    
        m_singleObject = (T_Object*)malloc(sizeof(T_Object));
    }

    // I have tried different function arguments (rvalue reference here, amongs others)
    inline void add(T_Object &&p_object)
    {
        // Allocate the template object
        new (m_singleObject) T_Object(p_object);
    }

    T_Object *m_singleObject;
};

int main()
{
    ObjectPool<FooClass> objPool;
    objPool.add(FooClass(1));
}

【问题讨论】:

    标签: c++ templates c++11 rvalue placement-new


    【解决方案1】:

    如果你使用T_Object&amp;&amp;,那肯定是在引用一个已经构造的T_Object,然后你需要在你的存储中创建一个新对象,所以这是另一个构造函数调用。

    你需要类似emplace_back的东西:

    template<class... Args>
    void emplace(Args&&... args)
    {
        // Allocate the template object
        ::new (static_cast<void*>(m_singleObject)) T_Object(std::forward<Args>(args)...);
    }
    

    将其称为objPool.emplace(1)。

    顺便说一句,add 采用T_Object&amp;&amp; p_object 的版本应该从std::move(p_object) 构造包含的对象。

    【讨论】:

    • 感谢您的回答。我添加了 void emplace() 方法,并且调用它非常有效。当我查看 push_back 时,我在 std::vector 容器中看到了这种方法,但是我并没有完全理解语法。有没有办法实现这一点,所以我可以用 (FooClass(1)) 而不是 (1) 来调用它?
    • @PaulA。你不能两全其美。 FooClass(1) 构造了一个临时的FooClass,所以总的来说它会调用构造函数至少两次。
    • std::vector.push_back 是如何做到的?因为,如果我用FooClass(1) 调用push_back,它只会调用构造函数一次。
    • @PaulA。我对此表示怀疑,除非您没有正确检测构造函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    • 2023-03-28
    • 2012-12-15
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多