Mar 21, 2012 at 2:07pm UTC
Hi, why is my program calling the function of the parent instead of the child?
Where the function is being called
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
std::vector<GameEntity> entity_list(0);
std::cout << "Entity list created" << std::endl;
b2Vec2 vs[5]; vs[0].Set(0,0); vs[1].Set(float (DISPLAY_WIDTH/32),0); vs[2].Set(float (DISPLAY_WIDTH/32),float (-DISPLAY_HEIGHT/32));
vs[3].Set(0,float (-DISPLAY_HEIGHT/32)); vs[0].Set(0,0);
std::cout << "Wall configuration created." << std::endl;
StaticWall wall(vs,6, physics_world, "Staticwall" ); // StaticWall is supposed to be a child of GameEntity
std::cout << "Wall initialised." << std::endl;
entity_list.push_back(wall);
std::cout << entity_list.size() << std::endl;
std::cout << "Spawned a wall" << std::endl;
entity_list[0].draw_self();// <-- This is where the wrong function gets called.
Declaration of GameEntity and StaticWall
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
#include "pinball.h"
class GameEntity{
public :
std::string test;
void virtual draw_self(){std::cout << "WRONG! GameEntity draw() called!" << test << std::endl;};
};
class StaticWall : public GameEntity{
public :
std::vector<Drawable_Line> drawList;
StaticWall(b2Vec2 vertices[], int vertex_amount, b2World & physics_world, std::string test){
b2BodyDef bodyDef;
bodyDef.type = b2_staticBody;
bodyDef.position.Set(0,0);
b2Body * body = physics_world.CreateBody(&bodyDef);
b2ChainShape chain;
chain.CreateChain(vertices, vertex_amount);
b2FixtureDef fixtureDef;
fixtureDef.shape = &chain;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
body->CreateFixture(&fixtureDef);
std::cout << "(Wall Init) Teststring: " << test << std::endl;
this ->test = test;
std::cout << "(Wall Init) Filling draw list." << std::endl;
drawList = std::vector<Drawable_Line>(5);
for (int i=0; i<vertex_amount-1;i++){
Drawable_Line line(vertices[i].x,vertices[i].y,vertices[i+1].x,vertices[i+1].y);
std::cout << "(Wall Init) Created draw line!." << std::endl;
drawList[i] = line;
std::cout << "(Wall Init) Draw line added to draw list!" << std::endl;
}
std::cout << "(Wall Init) Finished!." << std::endl;
}
void draw_self(){
std::cout << "Drawing static wall" << test << std::endl;
for (unsigned i=0; i < drawList.size(); i++) {
drawList[i].draw();
}
}
};
Last edited on Mar 21, 2012 at 2:08pm UTC
Mar 21, 2012 at 4:39pm UTC
std::vector<GameEntity> entity_list(0);
This means that everything in
entity_list is a
GameEntity . Because anything in the vector cannot be anything but a
GameEntity , methods called on objects in the vector will always be those of
GameEntity .
To get the behavior you want,
entity_list should contain pointers or references to
GameEntity .
1 2 3
StaticWall wall(vs,6, physics_world, "Staticwall" ); // StaticWall is supposed to be a child of GameEntity
entity_list.push_back(wall);
This is sometimes called shearing. The derived portion of the instance is simply lost when it's fed to a function taking an argument of type BaseClass.
Last edited on Mar 21, 2012 at 4:40pm UTC
Mar 30, 2012 at 4:09pm UTC
Ok, that's one difference from Java...
But this doesn't work: std::vector<*GameEntity> entity_list(0);
I get a compile error.
If I try to put *s in other places, it gives me other errors. How do I change my code to store pointers in the vector like you said?
Last edited on Mar 30, 2012 at 4:12pm UTC
Mar 30, 2012 at 5:02pm UTC
std::vector<GameEntity*> entity_list ;
However, you must make sure the objects which are pointed to aren't deallocated before the pointer is removed from entity_list or entity_list is destroyed.
In the first block of code it looks like the lifetime of entity_list and the wall you created would be the same, but it is something you should be aware of.
Mar 31, 2012 at 7:52am UTC
Ah, * after GameEntity, not before...
Ok, probably a complete noob question here: Does the data that the pointer points to have to be allocated on the heap?=
Last edited on Mar 31, 2012 at 8:44am UTC