Skip to main content
GameDev.net gamedev.net
🔒 Locked

Polymorphism and Lists

Started by medevilenemy Jun 16, 2007 at 8:15 PM 8 replies 900+ views
Original Post
medevilenemy
medevilenemy
I'm writing a system for handling ships in a new game of mine, and I've run into a bit of a problem -- mostly with my inexperience with using polymorphism. I have class Ship which inherits from a class Rotatable. Ship is meant to be a base class for more specialized ship classes (IE: Frigate, Corvette, etc). Whenever a new ship is spawned, it is placed into a list of ship objects (list allShips) and I use an iterator (list::iterator currentShip) to deal with each ship one by one. I then call class functions as needed (in the form currentShip->render() etc...). The problem is that when called, the function as defined in Ship is always called, not as defined in the subclass (Frigate, etc). Anyone know what I'm doing wrong? A bit of relevant code is below: Here is the list and ship handler function

list<Ship> Allships;
list<Ship>::iterator currentship;

void HandleShips()
{
    for(currentship = Allships.begin(); currentship != Allships.end(); currentship++)
    {
        currentship->RotateX(0.005); 
        currentship->Render();
    }
}

And here I create a couple of ship objects (of class TestShip) for testing purposes.

Allships.push_back(TestShip(100, 100, 0.0, 0.0, 0.0));
Allships.push_back(TestShip(100, 100, 0.0, 0.1, 0.0));

There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
medevilenemy
medevilenemy
I've read that, but in that case I have to dereference the pointer differently (as in a modification to the handleships function). How do you suggest I do that? Perhaps create a temporary copy locally?

[edit] Oh, and deleting the ship objects shouldn't be a problem, I fully intended to manually remove them upon their destruction/game exit.
[edit] Without changing the means of dereferencing, I get the following error: "RotateX has not been declared" and "Request for member of non-aggregate type before '(' token"

[Edited by - medevilenemy on June 16, 2007 10:52:28 PM]
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
medevilenemy
medevilenemy
[update] I changed the HandleShips() function above to the following
void HandleShips(){    Ship *cship;    for(currentship = Allships.begin(); currentship != Allships.end(); currentship++)    {        cship = *currentship;        cship->RotateX(-dx/1000);        cship->Render();    }}

and it seems to work fine with no errors, warnings, or apparant bugs. So thats that I suppose.

[edit] strike that... it runs, but it is still calling the functions from Ship and not the overridden functions from TestShip.
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
My_Mind_Is_Going
My_Mind_Is_Going
Maybe I'm being dumb and not understanding what's going on here because nobody has suggested this but have you declared the function in the base class as virtual? If you don't declare it virtual and then override in a derived class, the version of the function you'll end up calling will be determined by the type of pointer you're using although I don't really know that much about all this STL stuff so maybe that's not an issue here...
medevilenemy
medevilenemy
Good Idea, I'll try that, though I don't know if it will work properly with evreything (ie: render is defined inherited all the way from Rotatable and I dont know if virtual would have the same effect two generations later).
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
medevilenemy
medevilenemy
I stand thoroughly corrected, it works perfectly. Now I should be able to get specialized behavior type stuff working. Thanks again!
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
Captain P
Captain P
If you're calling delete on base class pointers, while you might be dealing with derived class objects, then make sure the base class destructor is also virtual - otherwise, only the base class destructor is called, resulting in a half-destructed object. Which likely falls into the realm of undefined behaviour, and that's not what you want. :)
medevilenemy
medevilenemy
Sure, I'll keep that in mind.

Kudos for another problem completely and effectively squashed [grin]. Gamedev++
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.

Topic Locked

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

Sign in to reply to this topic.