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

C++子类重写基类方法后如何正确调用子类版本方法

问题根源

你当前代码无法触发子类重写方法,是踩了C++多态实现的两个核心规则:

  • 基类需要被子类重写的方法没有加virtual关键字:C++默认对成员方法做静态绑定,编译阶段就根据参数/变量的声明类型确定调用的方法版本,不会在运行时判断对象的实际类型。
  • call_method使用值传递接收BaseClass类型参数:传入子类对象时会发生对象切片,子类独有的成员和虚表指针部分会被截断,函数内拿到的是纯BaseClass实例,自然只能调用基类版本的方法。
修复步骤
  1. 给基类中需要被重写的myMethod加上virtual关键字,开启运行时动态分派;C++11及之后版本建议在子类重写的方法后加override关键字,让编译器帮你检查重写的函数签名是否和基类一致,避免手误写错。
  2. 多态基类必须把析构函数也声明为virtual,否则通过基类指针/引用释放子类对象时会触发未定义行为。
  3. 把call_method的参数改成基类的引用或者指针,避免值传递导致的对象切片。

修复后的可运行代码:

#include <iostream>

using namespace std;

//基类
class BaseClass {
public:
    virtual void myMethod(){
        std::cout  << "Base class?" << std::endl;
    }
    // 多态基类必须声明虚析构函数
    virtual ~BaseClass() = default;
};

//子类
class SubClass1: public BaseClass{
public:
    // override关键字用于编译期校验重写正确性
    void myMethod() override {
        std::cout << "Subclass?" << std::endl;
    }
};

// 通用调用函数,传基类引用避免切片
void call_method(BaseClass& object){
    object.myMethod();
}


int main()
{
    BaseClass bc;
    SubClass1 sb1;

    // 直接调用子类方法,输出"Subclass?"
    sb1.myMethod();
    // 传入通用函数,现在也会输出"Subclass?"
    call_method(sb1);

    return 0;
}
其他可选实现

如果不需要强制所有传入类型继承自同一个基类,可以用模板实现编译期多态,没有虚函数的运行时开销,只要传入的类型实现了myMethod方法即可正常调用:

template<typename T>
void call_method(T& object){
    object.myMethod();
}

这种写法不需要修改基类代码,也支持任意符合接口要求的类型传入,灵活性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 01:42:23