You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
            }
        }
    }
};

额外优化点

  1. 所有指针操作添加空指针判断,避免运行时崩溃
  2. 虚继承场景下,由最派生类(VampireWerewolf)直接初始化虚基类(Creature),中间基类无需再传递基类参数,符合C++虚继承的构造规则
  3. 给VampireWerewolf::printInfo()添加override关键字,增强代码规范性

内容的提问来源于stack exchange,提问作者Reef Kenig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:28:10