dimanche 20 avril 2014

fonction - l'appel de méthode virtuelle de la classe de base C++ - Stack Overflow


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)




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();
}


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)



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();
}

0 commentaires:

Enregistrer un commentaire