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

C++继承链调用继承方法输出结果不符合预期问题求助

问题根因

你遇到的输出不符合预期的问题由两个C++语法特性共同导致:

  • C++的类成员变量不存在覆盖(override)行为:你在Bar类中定义的同名toPrint是仅属于Bar类的独立新成员,和父类Foo的私有toPrint是存储在对象内存不同位置的两个完全无关的变量。且Foo类的toPrint是private权限,Bar类本身就没有访问权限,你定义的同名变量只是“遮蔽”了父类变量名,本质上没有任何关联。
  • 虚函数调用匹配规则:你没有在Bar类中重写print()虚函数,所以从Base类runExample触发的虚函数调用最终会匹配到Foo类实现的print(),该方法访问的是Foo类作用域下的toPrint,值为Foo构造函数初始化的Hello Foo,完全不会用到Bar类中你新增的toPrint变量。

补充说明:和你熟悉的Kotlin不同,Kotlin中open属性重写会替换父类属性的访问逻辑,但C++的成员变量没有类似机制,私有成员对子类完全不可见,同名变量仅为独立的新成员。

符合代码复用要求的解决方案

你不需要在每个子类中重写print()方法,只需要调整父类成员变量的访问权限,移除Bar类中重复的toPrint定义即可:

  1. 修改foo.h,将toPrint的访问权限改为protected,这样子类可以直接访问继承到的该成员变量,不需要重复定义:
#pragma once
#include "../base/base.h"

class Foo : public Base {
    public:
        Foo();
    private:
        void print() override; // 新增override是C++虚函数重写的规范写法
    protected:
        const char* toPrint;
};
  1. 修改bar.h,删除你额外新增的toPrint定义,直接复用继承自Foo的成员:
#pragma once
#include "../foo/foo.h"

class Bar : public Foo {
    public:
        Bar();
};
  1. bar.cpp不需要修改逻辑,构造函数中赋值的toPrint会自动指向继承自Foo的成员变量:
#include "bar.h"

Bar::Bar() {
    toPrint = "Hello Bar";
}

修改后运行代码,调用的仍然是Foo类实现的print()方法,访问的toPrint已经被Bar的构造函数修改为Hello Bar,输出和你预期一致,完全复用了父类的打印逻辑,不需要重复实现print()。

内容的提问来源于stack exchange,提问作者Thomas Cook

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:06:02