C++纯虚函数重写异常:输出为0而非预期值
问题描述
运行以下C++代码后,输出结果为0,而非预期的角色名称和生命值。我尝试通过基类character定义接口,在子类entity中实现相关变量与方法,怀疑是不是虚函数未正确重写导致的问题?
#include <iostream> using namespace std; class character { private: public: character(string n, int h, int a){ } virtual int getHealth() = 0; virtual int getAttack() = 0; virtual string getName() = 0; virtual void updateHealth() = 0; virtual void updateAttack(int a) = 0; virtual void attackCharacter(character &b) = 0; virtual void print() = 0; }; class entity : public character { private: string name; int health; int attack; public: entity(string n, int h, int a) : character(n, h, a) { n = name; h = health; a = attack; } void updateAttack(int a) override { attack = a; } void attackCharacter(character &b) override { b.updateHealth(); b.getHealth(); } int getHealth() override { return health; } string getName() override { return name; } virtual void print() override {cout<<name<<" "<<health<<endl;} int getAttack() override { return attack; } void updateHealth() override { health = health - attack; } }; #include <iostream> #include "character.h" using namespace std; int main() { character* player = new entity("Player", 50, 5); entity* enemy = new entity("Enemy", 50, 5); player->print(); enemy->print(); }
问题分析与修复
你的问题不是虚函数重写错误,而是几个基础逻辑和语法错误导致的:
子类构造函数赋值顺序颠倒
在entity的构造函数里,你写的是n = name; h = health; a = attack;——这是把未初始化的成员变量值赋给了参数,而非把参数值赋给成员变量。正确写法应该是:entity(string n, int h, int a) : character(n, h, a) { name = n; health = h; attack = a; }更简洁的初始化列表写法:
entity(string n, int h, int a) : character(n, h, a), name(n), health(h), attack(a) {}原代码中成员变量未初始化,所以
print()输出的是随机垃圾值(大概率为0)。updateHealth方法逻辑错误
当前updateHealth的实现是让自身生命值减去自身攻击力,完全不符合攻击逻辑。需要调整设计:- 给基类的
updateHealth添加参数,接收受到的伤害值:virtual void updateHealth(int damage) = 0; - 子类重写该方法,用生命值减去伤害值:
void updateHealth(int damage) override { health -= damage; } - 修改
attackCharacter,传入当前对象的攻击力作为伤害:void attackCharacter(character &b) override { b.updateHealth(getAttack()); }
- 给基类的
冗余代码清理
- 基类
character是纯虚接口类,空构造函数无意义,可直接移除; main前重复包含<iostream>,还引用了不存在的character.h,需删除这些冗余内容。
- 基类
修复后的完整代码
#include <iostream> #include <string> using namespace std; class character { public: virtual int getHealth() = 0; virtual int getAttack() = 0; virtual string getName() = 0; virtual void updateHealth(int damage) = 0; virtual void updateAttack(int a) = 0; virtual void attackCharacter(character &b) = 0; virtual void print() = 0; }; class entity : public character { private: string name; int health; int attack; public: entity(string n, int h, int a) : name(n), health(h), attack(a) {} void updateAttack(int a) override { attack = a; } void attackCharacter(character &b) override { b.updateHealth(getAttack()); } int getHealth() override { return health; } string getName() override { return name; } void print() override { cout << name << " " << health << endl; } int getAttack() override { return attack; } void updateHealth(int damage) override { health -= damage; if (health < 0) health = 0; } }; int main() { character* player = new entity("Player", 50, 5); character* enemy = new entity("Enemy", 50, 5); player->print(); enemy->print(); // 测试攻击逻辑 player->attackCharacter(*enemy); cout << "After player attacks enemy:" << endl; enemy->print(); enemy->attackCharacter(*player); cout << "After enemy attacks player:" << endl; player->print(); delete player; delete enemy; }
内容的提问来源于stack exchange,提问作者Ferndle
相关产品推荐
相关产品推荐

