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定义即可:
- 修改
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; };
- 修改
bar.h,删除你额外新增的toPrint定义,直接复用继承自Foo的成员:
#pragma once #include "../foo/foo.h" class Bar : public Foo { public: Bar(); };
bar.cpp不需要修改逻辑,构造函数中赋值的toPrint会自动指向继承自Foo的成员变量:
#include "bar.h" Bar::Bar() { toPrint = "Hello Bar"; }
修改后运行代码,调用的仍然是Foo类实现的print()方法,访问的toPrint已经被Bar的构造函数修改为Hello Bar,输出和你预期一致,完全复用了父类的打印逻辑,不需要重复实现print()。
内容的提问来源于stack exchange,提问作者Thomas Cook
相关产品推荐
相关产品推荐

