Anne Quinn Anne Quinn - 3 months ago 11
C++ Question

How to add object with expensive dtor to vector without emplace_back()

I have an object

RenderBuffer
that creates an OpenGL Buffer as part of it's constructor, and destroys it as part of it's destructor. It's a very expensive operation. This object has no default constructor, so it's either usually put in an initialization list or pushed into the back of a vector if there's many of them:

Window::Window(Renderer & render)
: m_renderBuffer(render) // sometimes looks like this
{
m_multipleBuffer.push_back(RenderBuffer(render)) // othertimes can look like this
}


the latter instance with the vector causes the destructor to be called, causing problems.

I am using VS2010 which lacks the
emplace_back()
that would make this work. What can I do? Should I abandon the RAII type of coding style and give my classes an
init(...)
method? Is there a way to get this working with copy constructors? And if there is, is it worth the effort over just using initialization methods (move constructors for each class would be a lot of boilerplate)?

Answer

You could simply provide your own version of a move constructor. For example, you can provide a constructor which takes an additional "move" flag, and when the copy constructor is called for an object which has this flag set, it just performs a move instead of a copy.

This technique was described by Bjarne Stroustrup in his keynote at Going Native 2012, when asked how C++ developers implemented moves before C++11.

Also, while I haven't worked with this particular library, there is Boost.Move which emulates move semantics for C++03 compilers. Movable classes get special move constructors and move assignment operators which are distinguished by having a BOOST_RV_REF(T) argument and which are called using T a(boost::move(b)) or T a = boost::move(b).