Sylar
Sylar

Reputation: 357

Calling virtual method from base class C++

I'm new to C++ and i'm having a hard time figuring out what's wrong with my virtual functions. So, here's what i have:

GEntity.h

class GEntity
{
public:
    //...
    virtual void tick(void);
    virtual void render(void);
    //...
};

GEntity.cpp

//...
void GEntity::tick(void){}
void GEntity::render(void){}
//...

GLiving.h

class GLiving : public GEntity
{
public:
    //...
    virtual void tick(void);
    virtual void render(void);
    //...
};

GLiving.cpp

//...
void GEntity::tick(void){}
void GEntity::render(void){}
//...

Then i have other classes that derive from GLiving (Player, Enemy) which implement their own versions of this two methods: Player.h

class Player : public GLiving
{
public:
    //...
    void tick(void);
    void render(void);
    //...
};

Player.cpp

//...
void GEntity::tick(void)
{
    //Here there's some actual code that updates the player
}
void GEntity::render(void)
{
    //Here there's some actual code that renders the player
}
//...

Now, if i declare an object of class Player, and call the render/tick method, everything goes well, but i am in a situation in which i add my player to an arraylist (a struct i created) of GEntity, and then, when i get it back, i get it as a GEntity, and i need to call the render/tick methods without knowing it's derived class... I've tried with the code above, but i get an access violation in the line where i call either the render or tick method, on the extracted GEntity...
...is what i want even possible to achieve?
(sorry if my english is not so good, but i'm italian)

Upvotes: 3

Views: 2510

Answers (1)

juanchopanza
juanchopanza

Reputation: 227548

If you have an array of GEntity then, each time you "add" a derived type, the equivalent of this happens:

GEntity g;
Player p;
g = p; // object slicing, you assigned a Player to a GEntity object.
g.render(); // GEntity::render() gets called

On the other hand, you can use a pointer to a base class to access a derived method:

GEntity* g;
Player p;
g = &p;
g->render(); // calls Player::render()

So a way to deal with polymorphism in containers is to have arrays/containers of (preferably smart) pointers to the base class. This example uses raw pointers for simplicity, but you should use smart pointers in real code:

std::vector<CEntity*> entities;
entities.push_back(new Player);
entities.push_back(new GLiving);

// some c++11
for ( auto e : entities) {
  e->render();
}

Upvotes: 3

Related Questions