c – 为什么我们使用多态性指针?

我正在youtube上观看thenewboston的教程,我对多态性的问题很少.这是他的代码:

#include <iostream>
using namespace std;
class Enemy{


   protected:
   int attackPower;
public:
    void setAttackPower(int a){
    attackPower=a;
    }
};

class Ninja:public Enemy{
public:
    void attack(){
    cout<<"I am a ninja,ninja chop! -"<<attackPower<<endl;}
};

class Monster:public Enemy{
public:
void attack() {
cout<<"monnster must eat you!!! -"<<attackPower<<endl;
}
};

int main()
{
    Ninja n;
    Monster m;
    Enemy *enemy1=&n;
    Enemy *enemy2=&m;
    enemy1->setAttackPower(29);
    enemy2->setAttackPower(99);
    n.attack();
    m.attack();

}

我的问题是:我可以像这样在main()中编写代码(或者不应该我和为什么?):

Ninja n;
Monster m;
//Enemy *enemy1=&n;
//Enemy *enemy2=&m;
//enemy1->setAttackPower(29);
//enemy2->setAttackPower(99);
n.setAttackPower(99);
m.setAttackPower(29);
n.attack();
m.attack();

解决方法:

Can I write the code in main() like this […]

当然,你可以!原因是您的新示例不使用多态行为.与原始示例不同,原始示例隐藏了编译时代码中运行时类型的Enemy对象的知识,您重写的代码使类型可用.

如果没有指针或引用,这将是无法工作的:

void setPowerAndAttack(Enemy enemy, int power) {
//                     ^^^^^^^^^^^
//  This is not going to work without pointer/reference
    enemy.setAttackPower(power);
    attack();
}
...
Ninja n;
Monster m;
setPowerAndAttack(n, 99);
setPowerAndAttack(m, 29);

即使代码会编译,setPowerAndAttack中的Enemy也不会因object slicing而出现多态行为.

你需要让敌人成为指针或引用以保持多态行为:

void setPowerAndAttack(Enemy& enemy, int power)
//                          ^

非常重要:您需要在Enemy类中创建攻击函数virtual,以便具有任何多态行为.观看视频时不清楚:

class Enemy {
protected:
   int attackPower;
public:
    void setAttackPower(int a) {
        attackPower=a;
    }
    virtual void attack();      // <<== Add this line
    virtual ~Enemy() = default; // <<== Add a virtual destructor
};
上一篇:为什么这种封装破坏在C中起作用?


下一篇:java – 如何通过参数类型选择重载方法?