为什么我们使用多态指针
Why do we use pointers with Polymorphism?
我正在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();
我可以像这样用
main()
编写代码吗 [...]
当然,你可以!这样做的原因是您的新示例不使用多态行为。与原始示例不同,原始示例从编译时代码中隐藏了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);
即使代码可以编译,Enemy
setPowerAndAttack
也不会由于对象切片而表现出多态行为。
您需要enemy
成为指针或引用以保持多态行为:
void setPowerAndAttack(Enemy& enemy, int power)
// ^
非常重要:您需要在Enemy
类中virtual
attack
函数,以便具有任何多态行为。从观看视频中看不出这一点:
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
};
为什么我们使用多态指针?
因为间接寻址是实现动态多态性所必需的。指针是一种间接形式,引用也用于多态性。
我可以像这样在main()中编写代码吗(或者我不应该和为什么??
你可以,而且你应该这样做。中显示的类层次结构是非多态继承的一个示例。间接寻址不会增加任何有用的内容。
您的示例未使用多态性。
多态性可以简化为通过通用接口提供不同的功能。想想USB设备:键盘和闪存驱动器共享相同的USB端口,但提供不同的功能。
此示例将使用多态性:
#include <iostream>
using namespace std;
class Enemy
{
protected:
int attackPower;
public:
virtual ~Enemy() = default;
virtual void attack() = 0;
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); // not polymorphism: interface and functionality are from Enemy
enemy2->setAttackPower(99); // not polymorphism: interface and functionality are from Enemy
enemy1->attack(); // polymorphism: interface of Enemy, functionality of Ninja
enemy2->attack(); // polymorphism: interface of Enemy, functionality of Monster
}
相关文章:
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- Doees the 'this' 指针参与虚函数的多态行为
- 如何在基类指针向量的元素上应用重载的多态函数
- 具有智能指针的多态性
- 当目标指针不是基类的类型时,为什么允许dynamic_cast为多态类生成 null 指针?
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 无法初始化已知大小的矢量指针,该大小不会因多态性而更改
- 如何调用指针类型的方法(禁用多态性)?
- 当依赖关系和依赖关系都是多态时,在哪个继承级别存储依赖关系指针?
- 创建基类指针的向量并将派生类对象传递给它(多态性)
- 当我有多态指针时使用"rule of zero"
- 为什么我们使用多态指针
- 序列化多态指针的QVector
- 多态指针的类型id
- 指向成员函数的多态指针
- 使用多态指针调用函数
- 指向基类的基本多态指针
- 指向成员变量的多态指针
- 从多态指针检查类成员是否存在