[英]C++ Polymorphism setting derived classes to base class object
I am working on a game using C++ with the SDL library, and am having troubles with polymorphism. 我正在使用带有SDL库的C ++进行游戏,并且在多态方面遇到麻烦。 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
的基类和Knight
and Mage
派生类。 Pawn
includes functions that are used by Knight
and Mage
, but Knight
and Mage
have functions specific to themselves. Pawn
包括由使用的功能Knight
和Mage
,但Knight
和Mage
具有特定的功能对他们自己。
Lets say Pawn
has a function move()
, and Knight
and Mage
each have a function attack()
that does different things for each of them. 可以说
Pawn
有一个函数move()
,而Knight
和Mage
都有一个函数attack()
,它们对每个函数执行不同的操作。 I have created an object selectedPawn
in order to click between the Knight
and Mage
and select each of them. 我创建了一个
selectedPawn
对象,以便在Knight
和Mage
之间单击并选择它们中的每一个。
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 在有用的地方,您可以有一个使用
Pawn
指针的函数,并且它不知道它是Knight
还是Mage
,但是由于多态性,正确的函数被调用
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) 您无法在C ++中执行此操作(您可以在某些Smalltalk衍生语言中执行此操作)
What you probably want to do is create another class Attacker, with the Attack method as a pure virtual method. 您可能想要做的是创建另一个类Attacker,并将Attack方法作为纯虚拟方法。
Make Knight and Mage derive from Attacker as well as Pawn. 使Knight和Mage源自Attacker以及Pawn。
Use the dynamic_cast operator on selectedPawn to try and get an Attacker pointer from it. 在selectedPawn上使用dynamic_cast运算符尝试从中获取Attacker指针。 If the Attacker* is non-null, you can use it to call attack() on the selectedPawn.
如果Attacker *为非null,则可以使用它来调用selectedPawn上的Attack()。
Attacker* attacker = dynamic_cast<Attacker*>(selectedPawn);
if (attacker) {
attacker->attack();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.