我编写了以下代码,我无法理解为什么Enemy()构造函数被调用两次。另外作为一个侧面问题,我想问一下是否通过使它们成为虚拟来覆盖成员函数然后再次编写它们的定义是在类之间重写函数的“正确”方法。
#include <iostream>
using namespace std;
class Enemy {
public: Enemy();
virtual void attack();
};
Enemy::Enemy() {
cout << "\nEnemy created";
}
void Enemy::attack() {
cout << "\nattack inflicts 10 damage";
}
class Boss: public Enemy {
public: Boss();
virtual void attack();
};
Boss::Boss() {
cout << "\nYou encounter a boss";
}
void Boss::attack() {
cout << "\nattack inflicts 30 damage";
}
int main() {
Enemy enemy1;
enemy1.attack();
Boss boss1;
boss1.attack();
return 0;
}
答案 0 :(得分:5)
我无法理解为什么Enemy()构造函数被调用两次
因为它继承了它,Boss
的类型为Enemy
。构造Boss
时,会调用Boss
和Enemy
的构造函数。
// Redacted lines that aren't important.
Enemy enemy1;
Boss boss1;
以上两行有效地创建了两个Enemy
类型的实例。其中一个恰好不只是Enemy
,而是Boss
。但它仍然是Enemy
,因此为两个对象调用Enemy
的构造函数。
我想问一下,通过将成员函数设置为虚拟然后再次编写其定义来覆盖成员函数是否是在类之间覆盖函数的“正确”方法。
是的,是的。
答案 1 :(得分:1)
由于您从Boss
派生了Enemy
,因此Boss
是 Enemy
。您可以将此视为Boss
,其中包含一个不可见的Enemy
成员,因此当您创建Boss
时,其构造函数会调用Enemy
来初始化此“隐身” “会员。
关于你的第二个问题:是的,但不要忘记使用关键字 override
对此进行注释。
答案 2 :(得分:0)
Boss是Enemy的孩子。所以Enemy的构造函数在纯粹的Boss构造函数之前被调用。
Boss::Boss() : Enemy ()
{
cout << "\nYou encounter a boss";
}