I am working on a game using C++ with the SDL library, and am having troubles with polymorphism. My project includes a lot of code so I will try to use an example as best as I can.
I have a base class Pawn
and derived classes Knight
and Mage
. Pawn
includes functions that are used by Knight
and Mage
, but Knight
and Mage
have functions specific to themselves.
Lets say Pawn
has a function move()
, and Knight
and Mage
each have a function attack()
that does different things for each of them. I have created an object selectedPawn
in order to click between the Knight
and Mage
and select each of them.
Knight* knight = new Knight();
Mage* mage = new Mage();
Pawn* selectedPawn = new Pawn();
selectedPawn = knight;
selectedPawn->move(); //This does not give me any errors and runs as it should.
selectedPawn->attack(); //Error: class "Pawn" has no member "attack"
My question is, is there a way of making this possible? If not, am I totally missing the purpose of polymorphism or executing it in the wrong manner?
Your base class defines your interface
struct Pawn
{
virtual void move() = 0;
virtual void attack(Pawn*) = 0;
virtual ~Pawn() = default;
};
Your derived classes implement that interface, implementing their own specific details for each function
struct Knight : Pawn
{
void move() override;
void attack(Pawn*) override;
};
struct Mage : Pawn
{
void move() override;
void attack(Pawn*) override;
};
Now you can call those functions on a base class pointer, but because of polymorphism , the derived function will be called, and therefore the functionality specific to that derived instance
Pawn* piece1 = new Knight;
Pawn* piece2 = new Mage;
piece1->move(); // will call Knight::move
piece2->move(); // will call Mage::move
Where this becomes useful is you can have a function which takes a Pawn
pointer, and it doesn't know if it's a Knight
or Mage
, but because of polymoprhism, the correct functions get called
void do_move(Pawn* piece)
{
piece->move();
}
void do_attack(Pawn* aggressor, Pawn* piece)
{
aggressor->attack(piece);
}
piece1->attack(piece2); // Knight attacks Mage
piece2->attack(piece1); // Mage attacks Knight
You can't do this in C++ (you can do this in some Smalltalk-derived languages)
What you probably want to do is create another class Attacker, with the Attack method as a pure virtual method.
Make Knight and Mage derive from Attacker as well as Pawn.
Use the dynamic_cast operator on selectedPawn to try and get an Attacker pointer from it. If the Attacker* is non-null, you can use it to call attack() on the selectedPawn.
Attacker* attacker = dynamic_cast<Attacker*>(selectedPawn);
if (attacker) {
attacker->attack();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.