Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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
like image 557
lowglider Avatar asked May 31 '12 08:05

lowglider


People also ask

When should we use unique_ptr?

Use unique_ptr when if you want to have single ownership(Exclusive) of resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another.

What is std :: unique_ptr?

std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.

Can you copy unique_ptr?

A unique_ptr does not share its pointer. It cannot be copied to another unique_ptr , passed by value to a function, or used in any C++ Standard Library algorithm that requires copies to be made. A unique_ptr can only be moved.

Is unique_ptr moveable?

important!: since unique_ptr is a moveable type only, the compiler will warn us about attempts to copy the whole parent object.


2 Answers

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.

like image 189
juanchopanza Avatar answered Oct 20 '22 18:10

juanchopanza


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.

like image 32
James Hopkin Avatar answered Oct 20 '22 20:10

James Hopkin