Mohammad Hussein
Mohammad Hussein

Reputation: 39

Vector of pointers vs Vector of objects vs Vector on the heap

What is the use case of the following examples:-


vector<Object> collection;

vector<Object> *collection = new vector<Object>

vector<Object*> collection;(creating the object on the heap)

When do I need to create a vector of pointers over a vector of objects and doesn't the vector (or any STL container) allocate the elements on the heap?

Upvotes: 0

Views: 1006

Answers (2)

Galik
Galik

Reputation: 48675

Typically,

std::vector<Object> collection; // Always use this if possible

You should always look to storing your objects directly as values in a std::vector. The vector stores its contents dynamically on the heap.

This,

std::vector<Object>* collection = new vector<Object>; // NEVER use this

I can't think of any reason that would be useful. The vector already stores its elements dynamically on the heap and you can move the entire contents around cheaply and easily using std::move or std::swap if needed.

What you MIGHT need to do is have several components managing the lifetime of your vector. In that case a std::shared_ptr may be appropriate:

auto collection = std::make_shared<std::vector<Object>>(); // possible

The last one could be needed in various situations. You may, for instance, need a separate "view" of another vector sorted using different criteria:

std::vector<Object> collection; 
std::vector<Object*> collection_view; // avoid

However, that can be dangerous as it is easy for pointers to get invalidated, particularly when pointing to elements of another vector. If you need something like this, try to encapsulate all the data in one class.

A much more likely need is if you want to access the elements of your vector polymorphically. In which case the vector will be responsible for deleting the objects and should use a std::unique_ptr to ensure their proper deletion:

std::vector<std::unique_ptr<Object>> collection; // Polymorphism?

Polymorphism requires accessing objects through a pointer or a reference.

There are likely other possibilities, you can't completely generalize. But these are common rules of thumb.

Upvotes: 3

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123566

You almost never want a:

vector<Object> *collection = new vector<Object>

A std::vector does store its elements on the heap. Creating the vector itself dynamically adds no apparent benefit, but complications.


Only in rare cases a vector of raw pointers is exactly what you need.

vector<Object*> collection;(creating the object on the heap)

You do need a vector of pointers when you would need pointers also without the vector. For example when Object is a polymorphic type. Though then you would store smart pointers in the vector, not raw ones.

std::vector< std::shared_ptr<Object> > collection; // shared ownership
std::vector< std::unique_ptr<Object> > colleciton; // the vector is the only owner

Only when the pointers in the vector do not participate in ownership of the actual Objects you might want a vector of raw pointers. (In simple terms: ownership = who is responsible for managing the lifetime of the Objects).


The goto solution that fits roughly 99% of all cases is a

vector<Object> collection;

Upvotes: 3

Related Questions