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!
LVL 5
Hamlet081299Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

pgnatyukCommented:
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.

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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) {
                  it->foo();
            }

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?
0
pgnatyukCommented:
It's almost fine. Small fix:
(*it)->Foo();

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

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()
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

HappyCactusCommented:
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).

http://en.wikipedia.org/wiki/Smart_pointer
0
evilrixSenior 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.
http://www.cplusplus.com/reference/stl/vector/

>> 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.

http://www.experts-exchange.com/articles/Programming/Languages/CPP/C-Smart-pointers.html
0
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.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.