Should I use std::unique_ptr<T> in a std::vector member variable in my class?

3.2k views Asked by At

Imagine a class C that has a member variable m_MyList of type std::vector in which I want to store objects of type MyClass. C has two functions that add or remove objects in m_MyList. m_MyList should also be made accessible for consumers of C as they need to read the collection of MyClass objects. The external reader of the collection will have no means to change the collection, thus the MyClass objects are owned only by C.

Now my question: In C++11 style, what is the best T to store in the vector? The possibilities seem to be:

  • std::vector<MyClass>
  • std::vector<MyClass*>
  • std::vector<unique_ptr<MyClass>>, using std:move to push the unique_ptr into the vector
2

There are 2 answers

5
juanchopanza On BEST ANSWER

If the MyClass objects are owned by C, then the best option would be the simplest:

std::vector<MyClass>

The only reason I could see for using std::unique_ptrs here is if you need to keep pointers to a base class for polymorphism. In this case the unique_ptrs serve the purpose of releasing resources upon destruction of the vector. But then the C interface should not transfer ownership to the clients.

3
James Hopkin On

Raw pointers (std::vector<MyClass*>) are incorrect if C owns the objects. The other two are pretty similar with the following trade-offs:

  • std::vector<MyClass> - requires MyClass to be copyable and/or move-able
  • std::vector<unique_ptr<MyClass>> - requires (additional) dynamic allocations

The kind of operations being performed on the container may also be relevant. To take an extreme example, if MyClass is large and the container is being repeatedly shuffled, unique_ptr would be the better choice.