C++多继承中printInfo重复输出Creature信息的问题求助
解决C++多继承中虚基类信息重复打印的问题
问题原因
你遇到的Creature内容重复打印,核心原因是:
Vampire和Werewolf的printInfo方法都主动调用了Creature::printInfo()VampireWerewolf的printInfo同时调用了Vampire::printInfo()和Werewolf::printInfo(),导致Creature的信息被打印两次
虚继承解决的是多继承下基类实例重复的问题,但并没有改变你手动调用父类printInfo的逻辑,所以重复打印依然会发生。
解决方案:拆分打印职责
将基类信息打印和子类自身信息打印分离,让最派生类统一控制基类信息的打印次数,子类只负责自身信息的输出。
步骤1:修改Vampire类,分离自身打印逻辑
在Vampire.h中新增printSelfInfo方法,专门打印Vampire独有的信息,原有printInfo保持不变(供单独实例使用):
class Vampire : public virtual Creature { int m_lightSensitivity; Vampire** m_offsprings; public: // 原有构造函数不变,新增适配虚继承的构造函数 Vampire(): m_lightSensitivity(0), m_offsprings(nullptr) {} Vampire(char* name, int age, int numOfOffsprings, int lightSensitivity, Vampire** offsprings): Creature(name, age, numOfOffsprings), m_lightSensitivity(lightSensitivity) { if (numOfOffsprings <= 0) { m_offsprings = nullptr; } else { m_offsprings = new Vampire * [numOfOffsprings]; for (int i = 0; i < numOfOffsprings; i++) { m_offsprings[i] = offsprings[i]; } } } // 适配虚继承的构造:无需传递基类参数 Vampire(int lightSensitivity, Vampire** offsprings): m_lightSensitivity(lightSensitivity) { if (m_numOfOffsprings <= 0) { m_offsprings = nullptr; } else { m_offsprings = new Vampire*[m_numOfOffsprings]; for (int i = 0; i < m_numOfOffsprings; i++) { m_offsprings[i] = offsprings[i]; } } } // 新增:仅打印Vampire自身信息 void printSelfInfo() { cout << "===Vampire printInfo===" << endl << endl; cout << "Light sensitivity: " << m_lightSensitivity << endl; for (int i = 0; i < m_numOfOffsprings; i++) { if (m_offsprings && m_offsprings[i]) { cout << "- Offspring " << i + 1 << ": " << m_offsprings[i]->m_name << endl; } } } // 原有printInfo:调用基类+自身打印 virtual void printInfo() override { Creature::printInfo(); printSelfInfo(); } };
步骤2:修改Werewolf类,同样分离打印逻辑
在Werewolf.h中做类似修改:
class Werewolf: public virtual Creature { int m_werewolfHours, m_humanHours; Werewolf** m_offsprings; public: // 原有构造函数不变,新增适配虚继承的构造函数 Werewolf() : m_werewolfHours(0), m_humanHours(0), m_offsprings(nullptr) {} Werewolf(char* name, int age, int numOfOffsprings, int werewolfH, int humanH, Werewolf** offsprings): Creature(name, age, numOfOffsprings), m_werewolfHours(werewolfH), m_humanHours(humanH) { if (numOfOffsprings <= 0) { m_offsprings = nullptr; } else { m_offsprings = new Werewolf * [numOfOffsprings]; for (int i = 0; i < numOfOffsprings; i++) { m_offsprings[i] = offsprings[i]; } } } // 适配虚继承的构造:无需传递基类参数 Werewolf(int werewolfH, int humanH, Werewolf** offsprings): m_werewolfHours(werewolfH), m_humanHours(humanH) { if (m_numOfOffsprings <= 0) { m_offsprings = nullptr; } else { m_offsprings = new Werewolf*[m_numOfOffsprings]; for (int i = 0; i < m_numOfOffsprings; i++) { m_offsprings[i] = offsprings[i]; } } } // 新增:仅打印Werewolf自身信息 void printSelfInfo() { cout << "===Werewolf printInfo===" << endl << endl; cout << "Werewolf hours: " << m_werewolfHours << endl; cout << "Human hours: " << m_humanHours << endl; for (int i = 0; i < m_numOfOffsprings; i++) { if (m_offsprings && m_offsprings[i]) { cout << "- Offspring " << i + 1 << ": " << m_offsprings[i]->m_name << endl; } } } // 原有printInfo:调用基类+自身打印 virtual void printInfo() override { Creature::printInfo(); printSelfInfo(); } };
步骤3:修改VampireWerewolf的printInfo逻辑
让它只调用一次Creature::printInfo(),再分别调用两个父类的printSelfInfo(),最后添加自身信息打印:
class VampireWerewolf : public Vampire, public Werewolf { Creature** m_offsprings; public: // 修改构造函数:虚基类由最派生类直接初始化,中间类无需传递基类参数 VampireWerewolf( char* name, int age, int numOfOffsprings, int lightSensitivity, int werewolfHours, int humanHours, Creature** offsprings): Creature(name, age, numOfOffsprings), Vampire(lightSensitivity, nullptr), Werewolf(werewolfHours, humanHours, nullptr) { if (numOfOffsprings <= 0) { m_offsprings = nullptr; } else { m_offsprings = new Creature*[numOfOffsprings]; for (int i = 0; i < numOfOffsprings; i++) { m_offsprings[i] = offsprings[i]; } } } // 重写printInfo:统一控制打印流程 virtual void printInfo() override { // 仅打印一次Creature信息 Creature::printInfo(); // 打印Vampire自身信息 Vampire::printSelfInfo(); // 打印Werewolf自身信息 Werewolf::printSelfInfo(); // 打印VampireWerewolf自身信息 cout << "===VampireWerewolf printInfo===" << endl << endl; cout << "Number of offsprings: " << m_numOfOffsprings << endl; for (int i = 0; i < m_numOfOffsprings; i++) { if (m_offsprings && m_offsprings[i]) { cout << "- Offspring " << i + 1 << ": " << m_offsprings[i]->getName() << endl; } } } };
额外优化点
- 所有指针操作添加空指针判断,避免运行时崩溃
- 虚继承场景下,由最派生类(VampireWerewolf)直接初始化虚基类(Creature),中间基类无需再传递基类参数,符合C++虚继承的构造规则
- 给
VampireWerewolf::printInfo()添加override关键字,增强代码规范性
内容的提问来源于stack exchange,提问作者Reef Kenig
相关产品推荐
相关产品推荐

