C++中如何正确重写基类函数?解决子类继承函数调用问题
问题:子类继承的成员函数未调用重写后的子类方法
我定义了如下两个结构体,Child继承自Base:
struct Base{ double S1(int x){ return x*x; } double S2(int x){ return 2*x; } double S(int x){ return S1(x) + S2(x); } }; struct Child: Base{ double S1(int x){ return 0.0; } double S2(int x){ return 0.0; } };
其中S(int x)通过调用S1(int x)和S2(int x)生成结果。我在Child中重写了S1和S2,单独调用时确实生效了,但执行以下测试代码:
Child child; Base base; std::cout<<child.S(2.0)<<std::endl; // 输出8,不符合预期,仍调用基类的S逻辑 std::cout<<child.S1(2.0)<<std::endl; // 输出0,符合预期,调用子类的S1 std::cout<<base.S1(2.0)<<std::endl; // 输出4,符合预期,调用基类的S1 std::cout<<base.S(2.0)<<std::endl; // 输出8,符合预期,调用基类的S
输出结果为8 0 4 8,说明child.S()调用的是基类的S,进而使用了基类的S1和S2。如何让Child中继承而来的S()调用重写后的S1和S2?
解决方案
要实现这个需求,核心是利用C++的动态多态,需要将基类中的S1和S2声明为虚函数:
- 将基类的S1、S2改为虚函数
在Base类的S1和S2函数前添加virtual关键字,编译器会为这些函数生成虚表,支持运行时动态绑定到子类的重写版本:
struct Base{ virtual double S1(int x){ return x*x; } virtual double S2(int x){ return 2*x; } double S(int x){ return S1(x) + S2(x); } };
- 子类重写时建议使用override关键字(可选但推荐)
C++11及以上版本中,子类重写虚函数时可以添加override关键字,明确表示该函数是重写基类的虚函数,避免因函数签名不一致导致的隐式错误:
struct Child: Base{ double S1(int x) override { return 0.0; } double S2(int x) override { return 0.0; } };
修改后再运行测试代码,child.S(2.0)的输出会变为0,符合预期——此时S()会动态调用Child类中重写的S1和S2。
内容的提问来源于stack exchange,提问作者Botond
相关产品推荐
相关产品推荐

