By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,437 Members | 1,337 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,437 IT Pros & Developers. It's quick & easy.

Accessing subclasses of objects stored in container class.

P: 2
Hello, I am having trouble with a Polymorphism issue using container classes.

I have a longwinded and shortwinded version of my question:

Shortwinded version:

How can I store base class objects in a container class like a vector or list while still being able to access the individual subclass (virtual) functions? In my program, it is as if the functions aren't virtual.

Longwinded version:

I have a class "Poisson" which has several subclasses (say, "Predator and Prey").

I would like to address specific functions of one of these sublasses without knowing which subclass I'm dealing with.

For a specific instance of the class, I would (for example) do this via:

___________________________________________

Poisson thing1*;
Poisson thing2*;

...

thing1 = new Predator();
thing2 = new Prey();

...

thing1.think(); // calls Predator::think();
thing2.think(); // calls Prey::think();
thing1.move();
thing2.move();

...
___________________________________________


In my program, the elements are stored in some data structure and each program loop cycles through the elements. Since the elements themselves are constantly coming in and out of existence, I'd like to use a linked list type structure to store them. So I thought I'd try using container classes instead of throwing together my own list.

My problem is that when I add these elements to the list, they are all stored as the base class and I can not address the subclass' individual (virtual) functions.

Can anyone help me to understand how to store a <list> or <vector> of objects which inherit a common base class object such that I can address the subclass functions individually? In other words, how can I store a list of objects with the same functionality as the above code?

I've attached some sample code which shows what I'm doing now and the problem that arises.

Thanks for your time!

- Andrew


/* ************************************************** **** **
* Example Code *
************************************************** ******* */

Poisson *herbert;
Poisson *carnie;
Poisson *fernie;


vector<Poisson> vec;

int main(int argc, char *argv[])
{

// Create Objects which are each some subclass of Poisson class.
herbert = new Predator('r',12,42,"Roberto");
carnie = new Prey('y',23,6,"Kate");
fernie = new Tree('y',23,6,"Fern");

// Push objects on to list.
vec.push_back(*herbert);
vec.push_back(*carnie);
vec.push_back(*fernie);

// Cycle through list and reference abstract objects.

unsigned int index;
for (index = 0; index < vec.size(); index++)
{
Poisson *temp = &vec[index];
cout << temp->getName() << endl;
// This returns Poisson::getName() instead of (say) Prey::getName();
}
}
May 28 '07 #1
Share this Question
Share on Google+
3 Replies


weaknessforcats
Expert Mod 5K+
P: 9,197
Start off by not storing base class objects in your containers.

When you create a Prey and store it as a Poisson, a copy is made using the Poisson copy constructor. None of the Prey is copied. All that's in the container is the base portion of yout Prey object.

This phenomen is call slicing and it's bad news.

You must store Poisson pointers in your container.

Expand|Select|Wrap|Line Numbers
  1. vector<Poisson*> vec;
  2.  
You cannot make copies of your objects.

Further, storing pointers isn't such a good idea either when it comes to memory management. I suggest you read my article on Handle Classes in the C++ Articles section.

Lastly,

Your vector should not be a global variable. It should be local to main().
May 28 '07 #2

P: 2
Perfect. Made the changes and it works.

I didn't know about this clipping business.

Thanks for the advice!

- Andrew

Start off by not storing base class objects in your containers.

When you create a Prey and store it as a Poisson, a copy is made using the Poisson copy constructor. None of the Prey is copied. All that's in the container is the base portion of yout Prey object.

This phenomen is call slicing and it's bad news.

You must store Poisson pointers in your container.

Expand|Select|Wrap|Line Numbers
  1. vector<Poisson*> vec;
  2.  
You cannot make copies of your objects.

Further, storing pointers isn't such a good idea either when it comes to memory management. I suggest you read my article on Handle Classes in the C++ Articles section.

Lastly,

Your vector should not be a global variable. It should be local to main().
May 28 '07 #3

P: 5
Can you kindly show the changes in code??? It would help illustrate a lot.
Jun 8 '07 #4

Post your reply

Sign in to post your reply or Sign up for a free account.