0

I am having a problem with the following code, the overriden virtual functions are not executing. Not sure i'm doing wrong here probably a silly mistake. Anyway this is a game project and I have an array of objects which looks like this (the core::array is an irrlicht array, similar to the vector array)

core::array<GameObject> gameTargets;

This is the GameObject and Zombie definition

class GameObject {
protected:
    scene::ISceneNode* node;
public:
    int ID;
    int hitpoints;

    GameObject() {
        ...
    };

    void setNode(scene::ISceneNode* inode) {
        ...
    }

    virtual void shot(int dmg) {
        ... [BREAKPOINT HERE]
    }

    scene::ISceneNode* getNode() {
        return node;
    }
};

class Zombie : public GameObject {
public:
    static const enum Animation {
        ZOMBIE_WALK,
        ZOMBIE_HURT,
        ZOMBIE_DIE,
        ZOMBIE_TWITCH,
        ZOMBIE_ATTACK,
        ZOMBIE_IDLE
    };

    //We only want to accepted animated mesh nodes for this object
    Zombie(int hp, scene::IAnimatedMeshSceneNode* inode) {
        ...
    }

    //Override the shot function
    void shot(int dmg) {
        ... [BREAKPOINT HERE]
    }

    //Animate the zombie
    void setAnimation(Animation anim) {
        ...
    }
};

The member functions of the derived classes is never called, I am creating the objects like this

Zombie target(hp, (scene::IAnimatedMeshSceneNode*)node);

and calling the virtual function like this

for(int i = 0; (u32)i<level->gameTargets.size(); i++) {
    if(selectedNode == level->gameTargets[i].getNode()) {
        level->gameTargets[i].shot(b->damage);
    }
}

where b is a pointer to a bullet with a int variable damage and gameTargets contains GameObject

Danny Birch
  • 603
  • 4
  • 16
  • What happens if you declare void Zombie::shot(int) as virtual? What compiler are you using? – Joel Apr 19 '12 at 14:15
  • I'm using visual express c++, I tried using virtual functions in the derived but it didn't work, I suspect it is slicing what has been given in answers below – Danny Birch Apr 19 '12 at 14:18
  • @DannyBirch: Using the `virtual` keyword in the derived classes doesn't make a difference, you can also omit it if you prefer. What's important is that it's `virtual` in the base class. – Frerich Raabe Apr 19 '12 at 14:24

3 Answers3

7

I suspect that you're experiencing slicing because the gameTargets array contains values. I can't tell for sure because I don't know how the core::array template works. See What is object slicing? for a discussion about what slicing is.

To fix this problem, store either raw pointers as in

core::array<GameObject *> gameTargets;

Or use some sort of reference-counted pointer like

core::array<std::shared_ptr<GameObject>> gameTargets; // only available in C++11
Community
  • 1
  • 1
Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
1

array<GameObject> is a container of objects, not a container of pointers. Every object you add to it will be a GameObject and not one of the derived classes (if you add a derived class object, then it'll be "sliced").

Without knowing exactly what your core::array does, I suspect what you really intended to create is an array of std::unique_ptr<GameObject> (smart pointers) along the lines of

core::array< std::unique_ptr<GameObject> > gameTargets;
std::unique_ptr<GameObject> my_zombie(new Zombie);
gameTargets.push_back( my_zombie );
Ben Cottrell
  • 5,741
  • 1
  • 27
  • 34
0

a quick solution would be to make those parent functions as pure virtual functions, as in:

virtual void shot(int dmg) { } = 0; 

// edit and use array of pointer as suggested by Frerich Raabe

Ivica
  • 366
  • 1
  • 5
  • 2
    I think this wouldn't solve anything; in fact, the code probably doesn't even compile anymore because the `core::array` type cannot be instantiated anymore since `GameObject` is abstract due to the pure virtual method. – Frerich Raabe Apr 19 '12 at 14:18
  • yup, that's why I needed to edit my post; I assumed that he holds array of pointers... (don't know how I missed missing pointer in array) – Ivica Apr 19 '12 at 14:23