0
//GUITEXT
class guitext : public entity {
public:
    guitext(graphics *gfx, std::string _text, float _x, float _y, 
        float _size, float timeToLive);
    bool update(float deltaTime, gameworld *world);
    void draw(graphics *gfx);
};

void guitext::draw(graphics *gfx) { printf("draw"); }

//ENTITY

class entity {
public:
    virtual bool update(float deltaTime, gameworld *world) 
        { return false; }
    virtual void draw(graphics *gfx) { }
};

//GAMEWORLD

void gameworld::addEntity(entity e) { entitys.push_back(e); }

//MAIN 

for(int i = 0; i < (int)entitys.size(); i++) { entitys[i].draw(gfx); }

I have a vector in my gameworld class. When I add push a guitext entity to this vector I expect it to call the guitext::draw() function. But the base class function is being called. What am I doing wrong?

  • possible duplicate of [C++ Overriding Methods](http://stackoverflow.com/questions/1230006/c-overriding-methods) – CB Bailey Jan 03 '11 at 16:52
  • 1
    Comment on code: Rather than use the correct type you think casting away the problem `(int)entitys.size()` is a good idea! Learn **never** to use the C-Style cast operator and use the C++ case operators only when absolutely necessary. – Martin York Jan 03 '11 at 18:06

6 Answers6

6

You made a vector of entity. Those objects always have type entity. If you want to invoke polymorphism, they need to be pointers or references. How can a vector of entity store a guitext? There's not enough space, it doesn't know how to destroy it, etc etc.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • @Martin: Someone else already posted an answer with a link to slicing. I'm all for writing wonder answers, but I'm not gonna dupe. – Puppy Jan 03 '11 at 18:23
4

Was the vector declared as vector<entity>? Then only the base class part can be stored there, i.e. you lose polymorphism (which only works through pointer or reference in C++).

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
4

What you've done is a bit concealed variant of slicing.

Community
  • 1
  • 1
Yippie-Ki-Yay
  • 22,026
  • 26
  • 90
  • 148
0

You should define entitys to contain pointers to entity. Slightly edited example derived from your code.

#include "stdafx.h"
#include <vector>
#include <string>

class entity 
{
public:
    virtual void draw() { }
};

class guitext : public entity 
{
public:
    void draw()
    {
        printf("draw");
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<entity *> entitys;

    guitext g;

    entitys.push_back(&g); 

    for(int i = 0; i < (int)entitys.size(); i++) 
    { 
        entitys[i]->draw(); 
    }

    return 0;
}
Indy9000
  • 8,651
  • 2
  • 32
  • 37
0

You're storing Entitys, not pointers to objects of varying derived types of Entity.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
0

In addition, in your case it's not good idea to pass arguments by value, i suppose there will be very big quantity of objects that need to be redrawed. Better, by const reference, since functon doesn't change state of passed object inside.

StNickolay
  • 950
  • 2
  • 9
  • 21