Best way to maintain a list of objects?

I'm a bit new to C++, so excuse me if this is a stupid question.

I have a class "AItem", where each AItem can contain child AItems.  I thought this should be a pretty straightforward thing to do, but clearly my understanding of C++'s pointers is letting me down.

I had thought I could just use...
    typedef std::list<AItem> AItemList;

And then define...
    AItemList children;
... in my class.

It seemed to be working, but then when I started trying to access children, I got strange results.

I reread the documentation on list::push_back and found this...
"The content of this new element is initialized to a copy of x."

Certainly not what I wanted.  I don't want it to store "a copy of x" I want it to store x!

Maybe I should just use a dynamic array?  What would you recommend?

This seems like a pretty common thing to do, having a hierarchy of object applies to all sorts of applications, so surely it should be hard!
Who is Participating?
pgnatyukConnect With a Mentor Commented:
Seems like you need:
 typedef std::list AItemList;
You will have to write more code (create items as "new AItem"; delete all items in the  end, for example), but then it will work as you wish.

Hamlet081299Author Commented:
Thanks pgnatyuk.

I had already tried that, but that then gave me another problem when I then tried to access the items via an iterator.

            for (AItemList::iterator it = children.begin(); it != children.end(); ++it) {

Which used to work, now gives me...
invalid return type 'AItem **' for overloaded 'operator ->'

I'm sure it all just comes down to my ignorance of pointers, but how do I then make the above code work?
It's almost fine. Small fix:

It will work.
You know that you add element in this way:
AItem* item = new AItem;

And you need to clear the container in the end and delete all element from it. Something like:
  for (AItemList::iterator it = children.begin(); it != children.end(); ++it) {
          delete (*it);
   list.clear(); //erase from the begin() to end()
Never miss a deadline with

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

Or you can use some kind of smart pointer, like std::tr1::shared_ptr and std::tr1::weak_ptr (if your compiler supports it).
So you do not need to delete any object, when you're finished with it just forget it (i.e. get it out of scope).
evilrixConnect With a Mentor Senior Software Engineer (Avast)Commented:
generally speaking, unless you need to insert or remove from the middle of the "list" a vector is a better bet as it's more efficient in terms of memory usage and, unlike std::list, allows direct random access to elements (ie, access in O(1) time and not O(N) time).

Interface wise, the two containers are almost identical.

>> Maybe I should just use a dynamic array?  What would you recommend?
This is what vector is, unlike list -- which is a linked list.

Also, be careful about storing pointers to dynamically allocated objects in a container. That's a lot of heap allocated items to delete when you're done and, potentially, a lot of memory to leak in the face on an exception. I suggest using  smart pointer, which will clean memory up for you. If you want to know more about this take a look at the following article.
Hamlet081299Author Commented:
Thanks everyone for the help.  Good article on smart pointers evilrix, I added 100 points so I can give you something as well.

I'm not going to use the ref counted pointers for this, because the object creation and destruction is very tightly controlled already, but it's good to know.  I considered a vector too, but generally I don't have a need to access by index, but I do need to insert, delete, and move items mid-list for which list is more efficient.

I really just need to sit down and get my head around the way C++ does pointers especially in relation to objects.  I'm coming from a Delphi background, where objects are pointers and are treated as such.  The way that C++ implicitly makes copies of objects is a new paradigm for me.
All Courses

From novice to tech pro — start learning today.