C ++ Polymorphism设置派生类到基类对象

时间:2017-11-30 22:52:04

标签: c++ polymorphism

我正在使用C ++与SDL库进行游戏,并且遇到了多态性问题。我的项目包含很多代码,所以我会尽量使用一个例子。

我有一个基类Pawn和派生类KnightMagePawn包含KnightMage使用的功能,但KnightMage具有特定于自身的功能。

让我们说Pawn有一个函数move(),而KnightMage每个都有一个函数attack(),它们为每个函数执行不同的操作。我创建了一个对象selectedPawn,以便在KnightMage之间点击并选择每个对象。

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"

我的问题是,有没有办法让这成为可能?如果没有,我是否完全错过了多态的目的或以错误的方式执行它?

2 个答案:

答案 0 :(得分:2)

您的基类定义界面

struct Pawn
{
    virtual void move() = 0;
    virtual void attack(Pawn*) = 0;
    virtual ~Pawn() = default;
};

您的派生类实现该接口,为每个函数实现自己的特定细节

struct Knight : Pawn
{
    void move() override;
    void attack(Pawn*) override;
};

struct Mage : Pawn
{
    void move() override;
    void attack(Pawn*) override;
};

现在您可以在基类指针上调用这些函数,但由于多态,将调用派生函数,因此特定于该派生实例的函数

Pawn* piece1 = new Knight;
Pawn* piece2 = new Mage;

piece1->move(); // will call Knight::move
piece2->move(); // will call Mage::move

如果它变得有用,你可以使用一个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 

答案 1 :(得分:2)

您无法在C ++中执行此操作(您可以在一些Smalltalk派生的语言中执行此操作)

您可能想要做的是创建另一个类Attacker,将Attack方法作为纯虚方法。

让骑士和法师来自攻击者以及典当。

使用selectedPawn上的dynamic_cast运算符尝试从中获取攻击者指针。如果攻击者*非空,您可以使用它在selectedPawn上调用attack()。

Attacker* attacker = dynamic_cast<Attacker*>(selectedPawn);
if (attacker) {
  attacker->attack();
}