Virtual method being called instead of derived method

61 views Asked by At

i'm having trouble with an inherited function and i can't seem to figure out why it's behaving the way it is, and haven't been able to find an answer in other questions on SO.
I'm working on a small game and the inherited function is responsible for the interactions between the player and objects, if the player attempts to move to a space that is already inhabited by one of the various child classes of "Obstacle", it will call the "Bool GetMove" method of that object, which then executes its unique rules and returns a True if the game can place the player on the space, or False if it cant.

This is the base class header and its getmove method:

class Obstacle
{
public:
    const char* id;
    Obstacle* _properlyinitialized; //a pointer that points to the object itself, required by the teacher who gave the assignment.
    string Name;
    mutable bool Moveable;
    int x;
    int y;
    Obstacle();
    Obstacle(string Name, bool Moveable, int x, int y);
    virtual ~Obstacle();
    bool properlyInitialized();
    friend std::ostream& operator<<(std::ostream& stream, Obstacle& Obstacle);
    virtual bool getmove(const char*, std::vector<std::vector<std::vector<Obstacle> > >&);
    virtual void leavetile(std::vector<std::vector<std::vector<Obstacle> > >&);
};

bool Obstacle::getmove(const char* direction,std::vector<std::vector<std::vector<Obstacle> > >& _board){
    cout << "wrong getmove" << endl; //this method should never be called.
    return true;
};

One of the inherited classes and its getmove method:

class Barrel: public Obstacle
{
public:
    Barrel():Obstacle(){};
    Barrel(string Name, bool Moveable, int x, int y);
    ~Barrel(){};
    bool getmove(const char*, std::vector<std::vector<std::vector<Obstacle> > >&);
    void leavetile(std::vector<std::vector<std::vector<Obstacle> > >&);
};

bool Barrel::getmove(const char* direction,std::vector<std::vector<std::vector<Obstacle> > >& _board){
    cout << "barrel getmove" << endl;
    if(strcmp(direction, "OMHOOG") == 0){ //what direction to move?
        if(_board[this->x][this->y-1][0].properlyInitialized()){ //is that object already inhabited by an object?
            if(_board[this->x][this->y-1][0].Moveable){ //can the object be moved?
                if(_board[this->x][this->y-1][0].getmove(direction, _board){//move the object
                    _board[this->x][this->y-1][0] = *this; //move the barrel
                    _board[this->x][this->y-1][0]._properlyinitialized = &_board[this->x][this->y-1][0];
                    return true; //return true
                }
                else{
                    return false; //an object is in the way, the barrel can't be moved
                }
            }
            else{
                return false; //an object is in the way, the barrel can't be moved
            }
        }
        else{
            _board[this->x][this->y-1][0] = *this; //move the barrel
            _board[this->x][this->y-1][0]._properlyinitialized = &_board[this->x][this->y-1][0];
            return true; //return true
        }
    } //This is for direction "up", i left the other directions out because they're almost equal.

The method is called as follows:

//"this" is a board object
if(this->playfield[this->_player->x][(this->_player->y)-1][0].getmove(direction, this->getBoard())){
    //do some stuff
}

I have considered changing the Obstacle object to a pure virtual object, but i need dummy "Obstacle" objects elsewhere, so this isn't an option.

1

There are 1 answers

0
Cory Kramer On

The second argument of getmove should be a

std::vector<std::vector<std::vector<Obstacle*>>>&

Note that the inner most vector is of Obstacle* and not Obstacle? This way the correct virtual function will get called, and more importantly, you won't run into object slicing