code code - 8 months ago 40
C++ Question

Use case of smart pointers in stl data structures

I wrtoe this code to store objects on the heap. Works fine... but I wonder about the "need" or perhaps better said any benefit to writing code like this. Wouldn't STL data structures like deque already do what I wrote here automatically, that is to say, store the objects on the heap?

In case it isn't clear, the sytax I used
data.push_back( shared_ptr(new Vehicle("aba")) );
makes it store objects on heap, but wouldn't
data.push_back( Vehicle("aba") );
do the same by default?

then I could pass to functions a reference to the data structure and it would be equally lean either way, no? At this point I;m questioning whether there is really any use case for bothering with smart pointers when the objects stored are stored in a an STL data structure. Perhaps I should just let C++ auto manage this and then pass around smart pointers to the data structure itself, or just a reference to it.

deque<shared_ptr<Vehicle>> data;
data.push_back( shared_ptr<Vehicle>(new Vehicle("aba")) );
data.push_back( shared_ptr<Vehicle>(new Vehicle("bobo")) );
data.push_back( shared_ptr<Vehicle>(new Vehicle("cici")) );
data.push_back( shared_ptr<Vehicle>(new Vehicle("dede")) );
data.push_back( shared_ptr<Vehicle>(new Vehicle("efee")) );

for(unsigned int i =0; i < data.size(); i++ )
cout <<>getName() << endl;



for(deque<shared_ptr<Vehicle>>::iterator i = data.begin(); i != data.end(); )
cout << (*i)->getName() << endl;

Answer Source

The advantage of using deque<Vehicle> data; is you don't have to go through so many abstractions to get the data. And you data has better locality for access.

The disadvantage is that you can't save a reference, pointer or iterator to them in other list/queues/variables as every erase or insert invalidates them.

Using deque<Vehicle *> data; turns the previous on the head, you now have to go through the pointer to the data and might lose some access locality. But you can now save pointers to the vehicles in other places. But beware that when you delete the vehicle in one place all other pointers become invalid, and if accessed cause undefined behaviour like crashes.

Using deque<shared_ptr<Vehicle>> data; solves the last problem at the cost of more abstraction. Now deleting the Vehicle from one queue doesn't invalidate it in others. Also it gives the very nice feature that when the last reference to it disappears, the vehicle get deleted.

Neither of shared_ptr nor raw pointer can magically remove the vehicle from all lists or queue it is in, if you decide that it should disappear globally.