c++ - 为什么我们在多态性中使用指针?

标签 c++ polymorphism

我正在观看来自 thenewboston 的教程在 youtube 上,我几乎没有关于多态性的问题。这是他的代码:

#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 而表现出多态行为.

您需要将enemy 设为指针或引用以保持多态行为:

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

非常重要:你需要制作attack函数virtualEnemy 类中,以便完全具有任何多态行为。从视频看不清楚:

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++ - 为什么我们在多态性中使用指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41568512/

相关文章:

ruby-on-rails - Rails - 如何在某些事件上给用户通知消息

.net - EF4 无法将具体类型转换为接口(interface)

c++ - 如何在 VS2005 中提高大型 C++ 应用程序的链接性能

c++ - 纹理未在屏幕上绘制

c++ - 如何在 C++ 中不使用 cin 扫描字符串?

c++ - 试图输出 exe 文件中的所有内容

c++ - 高维数据如何映射到特征类型?

php - 如何使用 id 和类型名称加载 Laravel 模型?

c++ - Operator== 抽象类和 shared_ptr 的重载

c# - 继承和 'Curiously Recurring Template Pattern'