使用placement new的rvalue引用(与std :: vector.push_back类似的功能)

时间:2015-09-04 01:13:36

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

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

如何实现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));
}

1 个答案:

答案 0 :(得分:5)

如果你选择T_Object&&,那必须引用已经构造的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的{​​{1}}版本应该从T_Object&& p_object构建包含的对象。