C++ 如何在不使用emplace_back()的情况下将具有昂贵dtor的对象添加到向量

C++ 如何在不使用emplace_back()的情况下将具有昂贵dtor的对象添加到向量,c++,visual-studio-2010,vector,raii,C++,Visual Studio 2010,Vector,Raii,我有一个对象RenderBuffer,它创建一个OpenGL缓冲区作为其构造函数的一部分,并作为其析构函数的一部分销毁它。这是一个非常昂贵的手术。此对象没有默认构造函数,因此通常会将其放入初始化列表中,或者如果存在多个构造函数,则会将其推到向量的后面: Window::Window(Renderer & render) : m_renderBuffer(render) // sometimes looks like this { m_multipleBuffer.push

我有一个对象
RenderBuffer
,它创建一个OpenGL缓冲区作为其构造函数的一部分,并作为其析构函数的一部分销毁它。这是一个非常昂贵的手术。此对象没有默认构造函数,因此通常会将其放入初始化列表中,或者如果存在多个构造函数,则会将其推到向量的后面:

Window::Window(Renderer & render)
    : m_renderBuffer(render) // sometimes looks like this
{
    m_multipleBuffer.push_back(RenderBuffer(render)) // othertimes can look like this
}
向量的后一个实例导致调用析构函数,从而导致问题


我使用的是VS2010,它缺少使这项工作正常的
emplace\u back()
。我能做什么?我应该放弃RAII类型的编码风格,给我的类一个
init(…)
方法吗?有没有一种方法可以让它与复制构造函数一起工作?如果有的话,仅仅使用初始化方法是否值得付出努力(每个类的移动构造函数都有很多样板文件)

考虑使用指向对象的智能指针向量。例如:

vector<shared_ptr<RenderBuffer> >  m_multipleBuffer;
向量m_多重缓冲;
当然,这意味着您必须在需要实际的RenderBuffer时取消对指针的引用,而实际的RenderBuffer取决于程序的其余部分,这可能是实际的,也可能不是实际的,但是如果它是实际的,您可以避免不必要的RenderBuffer复制构造和销毁


请注意,复制构造函数也可能是一个昂贵的操作,除非RenderBuffer被设计为共享底层OpenGL缓冲区。

您只需提供自己版本的移动构造函数即可。例如,您可以提供一个具有附加“移动”标志的构造函数,当为设置了该标志的对象调用复制构造函数时,它只执行移动而不是复制

这种技术是在Bjarne Stroustrup的《在本地2012》中描述的,当被问及C++开发人员如何在C++ 11之前实现移动时。


另外,虽然我还没有使用过这个特定的库,但是有一个库模拟了C++03编译器的移动语义。Movable类得到特殊的move构造函数和move赋值操作符,它们的区别在于有一个
BOOST\u RV_REF(T)
参数,并使用
ta(BOOST::move(b))
ta=BOOST::move(b)
push_back
调用它们,通常有一个右值引用构造函数,允许移动它。请记住,尽管VS2010没有实现C++11(或者只提供部分支持),但这可能不会发生pointer@jaggedSpire-如果可以的话,我想让它们在内存中具有感染力,因为它们会在frame@AnneQuinn那你能用boost.container吗?该库似乎包含许多类似向量的容器,在C++11之前具有移动支持和模拟移动支持。您是否可以使用“placement new”作为emplace_back()的粗略替代品?顺便说一句,出于性能原因,将对象保留在连续内存中被高估了。在这种情况下,我做了很多分析,很少有人认为连续分配的好处大于实施限制的成本。