Roast Beef
Roast Beef

Reputation:

How do I override in C++?

I can't get method overriding to work. Right now I have a class called Sprite, and two subclasses; Let's call them Goomba and Koopa. Instances of Koopas and Goombas are stored in an std::list of sprites called spriteList, and an iterator goes through this list and calls each sprite's behave() function.

I can get this to work with Goombas alone, by defining the behavior function as Sprite::behave(). But if I try to do the same thing with Koopas, the compiler gets mad because Sprite::behave() is already defined in Goomba. What am I doing wrong? I get the feeling that the answer is an extremely simple syntax issue, but looking online yielded no examples that looked quite like my code.

I'll paste some code, hopefully it'll help. This isn't my exact source code, so I apologize for any typos.

//Sprite.h:
#ifndef SPRITE_H
#define SPRITE_H

class Sprite {
private:
    float xPosition; float yPosition;
public:
    Sprite(float xp, float yp);
    void move(float x, float y); //this one is defined in Sprite.cpp
    void behave(); //this one is NOT defined in Sprite.cpp
};
#endif 


//Goomba.h:
#ifndef GOOMBA_H
#define GOOMBA_H
#include "Sprite.h"

class Goomba : public Sprite {
public:
    Goomba(float xp, float yp);
    void behave();
};
#endif 


//Goomba.cpp:
#include "Goomba.h"

Goomba::Goomba(float xp, float yp): Enemy(xp, yp) {}
void Sprite::behave(){
    Sprite::move(1, 0);
}


//Koopa.h looks just like Goomba.h


//Koopa.cpp
#include "Koopa.h"

Koopa::Koopa(float xp, float yp): Enemy(xp, yp) {}
void Sprite::behave(){
    Sprite::move(-2, 1);
}

Upvotes: 0

Views: 113

Answers (2)

user197015
user197015

Reputation:

In both Koopa.cpp and Goomba.cpp you are defining Sprite::behave. This results in two definitions, as your toolchain told you. You want to define Koopa::behave and Goomba::behave, respectively, in those files.

You also want to define Sprite::behave in Sprite.cpp (you said you currently do not define it anywhere).

You will also want to make Sprite::behave a virtual function in order to get the polymorphic behavior you are after working the way you likely expect it to:

class Sprite {
  // ...
  // You can either define Sprite::behave in Sprite.cpp or change the declaration to:
  // virtual void behave() = 0;
  // to make it "pure virtual," indicating that subclasses must provide an implementation.
  virtual void behave();
};

In Goomba.cpp, for example:

#include "Goomba.h"

Goomba::Goomba(float xp, float yp): Enemy(xp, yp) {}
void Goomba::behave(){
  ...
}

Upvotes: 0

Cory Kramer
Cory Kramer

Reputation: 117856

In Sprite you have to declare the function as virtual

virtual void behave();

Then in Goomba you should state that you are going to override that function

virtual void behave() override;

Note: The override keyword is new as of C++11

Upvotes: 1

Related Questions