C++中调用父类findPath时使用子类重写的addPoint方法的实现方案
解决C++子类调用父类方法时复用子类重写函数的问题
这是个典型的C++多态应用场景问题,核心在于成员函数的绑定方式。你当前的代码之所以达不到预期效果,是因为父类的addPoint没有启用动态绑定机制。
问题根源分析
在你的原始代码中,addPoint是普通成员函数,编译器会进行静态绑定——编译阶段就确定调用A::addPoint,不管实际调用的对象是A还是它的子类B。这就是为什么B调用findPath时,依然执行的是父类的addPoint逻辑。
最优解决方案:使用虚函数实现动态绑定
只需要把父类A中的addPoint声明为虚函数,就能让程序在运行时根据对象的实际类型,动态选择对应的addPoint版本。这样既不用复制findPath代码,又能复用子类的重写逻辑。
修改后的完整代码示例:
#include <vector> using namespace std; class A { public: vector<int> path; // 将addPoint声明为虚函数,启用动态绑定 virtual void addPoint(int num) { path.push_back(num); } vector<int> findPath() { path.clear(); // 清空路径,避免残留数据干扰结果 for (int i = 1; i <= 10; i++) { // 调整循环范围匹配你给出的示例结果 addPoint(i); } return path; } }; class B : public A { public: // C++11及以上建议加override关键字,编译器会检查是否正确重写父类虚函数 void addPoint(int num) override { path.push_back(num * num); } };
验证测试代码
#include <iostream> int main() { A a; auto pathA = a.findPath(); cout << "A.findPath(), path = {"; for (size_t i = 0; i < pathA.size(); i++) { if (i > 0) cout << ","; cout << pathA[i]; } cout << "}\n"; B b; auto pathB = b.findPath(); cout << "B.findPath(), path = {"; for (size_t i = 0; i < pathB.size(); i++) { if (i > 0) cout << ","; cout << pathB[i]; } cout << "}\n"; return 0; }
运行结果(符合你的期望)
A.findPath(), path = {1,2,3,4,5,6,7,8,9,10}
B.findPath(), path = {1,4,9,16,25,36,49,64,81,100}
额外说明
override关键字是C++11的特性,它能帮你避免因函数名拼写错误、参数类型不匹配导致的“伪重写”问题,建议养成使用习惯。- 如果
A只是作为基类,不需要直接实例化,可以把addPoint声明为纯虚函数(virtual void addPoint(int num) = 0;),这样A就变成抽象类,只能被继承,不能直接创建对象,更符合面向对象设计的规范。
内容的提问来源于stack exchange,提问作者robotguy63
相关产品推荐
相关产品推荐

