Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing a List of Objects

Tags:

c++

pointers

Let's say I have a generic Object class, and a generic List class. I want to maintain a list of these Objects. Should I store them as List<Object> or List<Object*>?

If I use List<Object> and I have a method like:

if(some_condition) {
    Object obj;
    myObjectList.append(obj);
}

And my list class only keeps a reference to the object, so as soon as that if statement terminates, the object is destroyed, and the object I pushed becomes invalid. So then I end up doing something like:

Object *obj = new Object;
myObjectList.append(*obj);

So that it doesn't get destroyed. But now the objects are undeletable, no? Because now they're stored safely in the List as Objects, not pointers to Objects, so I can't call delete on them... or will they automatically be destroyed when they're popped from the list?

In that case, I should probably use List<Object*> and delete them from the list when I'm done with them, no?

So confused... I'm sure I have a fundamental misunderstanding here somewhere.

like image 700
mpen Avatar asked Aug 21 '09 03:08

mpen


3 Answers

EDIT: As mentioned in a comment boost::ptr_list is even better since it is more efficient and has the same net effect as a std::list<boost::shared_ptr<T> >.


EDIT: You mention that you are using Qt in your comment. If you are using >= 4.5 you can use Qt's QList and QSharedPointer classes like this:

QList<QSharedPointer<Object> > object_list;
object_list.push_back(QSharedPointer<Object>(new Object));

I would recommend you use std::list<>. You also likely just want to store pointers to the objects so they aren't being copied all of the time.

So bottom line is:

Let's say you have a class named Object. You should do this:

std::list<boost::shared_ptr<Object> > object_list;
object_list.push_back(new Object);

For c++11/14, no need for boost, just use the standard smart pointers:

std::list<std::shared_ptr<Object>> object_list;
object_list.push_back(std::make_shared<Object>());

By using shared pointers, the objects will get cleaned up automatically when they are removed from the list (if there are no other shared_ptrS also pointing to it).

You could have a list<Object *>. But given your experience level, I feel that a reference counted pointer would be much easier for you to work with.

In that case, I should probably use List and delete them from the list when I'm done with them, no?

Yes, this is a viable option, but I highly recommend smart pointers to avoid the "...and delete them from the list..." step entirely.


NOTE:

also the example code you gave:

Object *obj = new Object;
myObjectList.append(*obj);

is probably not what you wanted, this makes a new object on the heap, they puts a copy of that in the list. If there is no delete obj after that, then you have a memory leak since raw pointers are not automatically deleted.

like image 184
Evan Teran Avatar answered Sep 23 '22 18:09

Evan Teran


In the first case the Object is copied and only the original is destroyed. The other instance is kept in the list.

In the second version you can use the List destructor to delete the stored objects.

like image 40
stribika Avatar answered Sep 25 '22 18:09

stribika


as with "all" things there is no one answer - the devil's in the details of what you want to do, or what your constraints are.

If the objects are lightweight and do not involve deep copying it's going to be more efficient to store the little things as copies. Otherwise, the overhead of smartish pointers is more than is warranted. If you are polymorPHic then you could use templated lists.

if it's more important to minimize copying, and eliminate redundant code from template instantiations, then use a list of smart, shared pointers.

Or use a list of naked pointers, use new/delete, and be meticulous with your pointer ownership.

Any list will act like a list, so the choice of list implementation is dependent on factors you aren't enumerating here.

like image 26
user143506 Avatar answered Sep 25 '22 18:09

user143506