Skip to main content
gamedev.net
🔒 Locked

A basic C++ question about classes

Started by Jotaf Feb 13, 2008 at 9:57 AM 5 replies 1.3k views
Original Post
Jotaf
Jotaf
Hi. I've got a question, I'm sure it's pretty basic, but I'd like to know what the options are. I have a (STL) list of class instances, all of them of different classes, but all derived from a particular base class. There's a virtual function in the base class implemented by the derived classes. I want to just pick an object in the list and call this function, but I'm under the impression that unless I re-cast it to the right (derived) type (which I don't know!), the base virtual function will be called instead of the derived one? Is that right or not, and if it is, what are the alternatives? (BTW, when copying one of these lists or manipulating them, the original derived classes will be maintained right? It won't do something stupid like copying one of the instances as if it was of the base class, even though the list is defined as a list of instances of the base class?)
aaulia
aaulia
It will call the derived one and yes the original derived class will be maintained, it just stored as a base class pointer.

SiCrane
SiCrane
If the function is virtual then calling it on a base class pointer will call the derived class' version.
riku
riku
You cannot store derived classes in a container for a base class. If you attempt to do Base base = Derived(), object slicing will occur. If you want to use inheritance and polymorphism, you will need to use references or pointers. In other words, your list cannot be std::list but rather std::list.

When using pointers, the usual problems occur. You have to take care that everything is deallocated (which is not that hard), even when exceptions occur (which requires a lot of attention). The good thing is that someone else has already thought about this one and we have boost.ptr_container and boost.shared_ptr to help with this. So, rather than using std::list, you could use boost::ptr_list or std::list > to get rid of the pointer issues. The former is probably better unless you need shared ownership (which might not be a good idea).

Hope this helps,
-Riku

Zahlman
Zahlman
I have no idea where you got that "impression". The whole point of 'virtual' is to avoid having to know the type ahead of time.

It's easy to make it work, but you can't put derived objects into a "slot" reserved for a base object - they don't "fit". For this reason, we usually add a layer of indirection - but beware memory management issues! The Boost library can help you out here: consider for example boost::ptr_list, or a std::list of boost::shared_ptr to whatever.
Jotaf
Jotaf
I'm sure it was a mistake in my code that gave me that impression. A long coding session and suddenly shoehorning a feature like this left me with messy code and really confused! Thank you very much to y'all, I'll probably use the boost library then :)
Jotaf
Jotaf
As a follow-up, I'm using boost::ptr_map and ptr_list, and they work wonderfully.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.