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

C++多态设置将类派生到基类对象 我正在使用C++与SDL库进行游戏,并且遇到多态性问题。我的项目包含很多代码,所以我会尽量使用一个例子,c++,polymorphism,C++,Polymorphism,我有一个基本类兵和衍生类骑士和法师。典当包括骑士和法师使用的功能,但骑士和法师有自己特有的功能 假设兵有一个功能移动,骑士和法师都有一个功能攻击,为他们每个人做不同的事情。我已经创建了一个对象selectedPawn,以便在骑士和法师之间单击并选择他们中的每一个 Knight* knight = new Knight(); Mage* mage = new Mage(); Pawn* selectedPawn = new Pawn(); selectedPawn = knight; selec

我有一个基本类兵和衍生类骑士和法师。典当包括骑士和法师使用的功能,但骑士和法师有自己特有的功能

假设兵有一个功能移动,骑士和法师都有一个功能攻击,为他们每个人做不同的事情。我已经创建了一个对象selectedPawn,以便在骑士和法师之间单击并选择他们中的每一个

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"

我的问题是,有没有办法做到这一点?如果不是,我是否完全没有理解多态性的目的,或者以错误的方式执行它?

基类定义了接口

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

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
这变得有用的地方是,你可以有一个函数,它接受一个兵指针,它不知道它是骑士还是法师,但由于多面体,正确的函数会被调用

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 

基类定义了接口

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

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
这变得有用的地方是,你可以有一个函数,它接受一个兵指针,它不知道它是骑士还是法师,但由于多面体,正确的函数会被调用

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 

<>你不能在C++中这样做,你可以在一些SimultTalk派生语言

中这样做 您可能想做的是创建另一个类攻击者,将攻击方法作为纯虚拟方法

使骑士和法师从攻击者和典当中衍生出来

在selectedPawn上使用dynamic_cast操作符尝试从中获取攻击者指针。如果攻击者*非空,则可以使用它调用对所选典当的攻击

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

<>你不能在C++中这样做,你可以在一些SimultTalk派生语言

中这样做 您可能想做的是创建另一个类攻击者,将攻击方法作为纯虚拟方法

使骑士和法师从攻击者和典当中衍生出来

在selectedPawn上使用dynamic_cast操作符尝试从中获取攻击者指针。如果攻击者*非空,则可以使用它调用对所选典当的攻击

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


。如果骑士、法师和典当都是从包含虚拟函数的同一父类派生的,那么你的指针应该是基本类型,而不是派生类型。你的意思是让它们像典当*骑士=新骑士一样吗?@Dallas他们不是有一个共同的基类吗?我有一个基本类典当以及派生类骑士和法师。Pawn是基类..指针应该是基类,而不是派生类型(如果是Knight),法师和典当来自同一个包含虚拟功能的父类。你的意思是让它们像典当*骑士=新骑士一样吗?@Dallas他们没有共同的基类吗?我有一个基类典当和派生类骑士和法师。典当是基本职业。我有一个基本职业典当和衍生职业骑士和法师。Pawn是基类。@Fred Larson-但Pawn没有攻击方法,听起来他不想将它添加到Pawn中。如果是这样,这种设计就违背了多态性的目的。这个程序,或者至少是代码的这一部分,不会比一个大开关或者if块更好,多态性应该会消除一些东西。我有一个基类Pawn和派生类Knight和Mage。Pawn是基类。@Fred Larson-但Pawn没有攻击方法,听起来他不想将它添加到Pawn中。如果是这样,这种设计就违背了多态性的目的。这个程序,或者至少是代码的这一部分,不会比一个大开关或者if块更好,多态性应该会消除它。你忘了虚拟析构函数。严重错误@正如Ivan所指出的,Dallas不要忘记基类中的虚拟析构函数!编辑答案以将其添加到虚拟析构函数中。严重错误@正如Ivan所指出的,Dallas不要忘记基类中的虚拟析构函数!编辑答案以将其添加到