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

为何通过基类成员函数调用虚函数仍执行派生类版本?

为什么基类成员函数内调用虚函数,仍会执行派生类的实现?

在下面的C++代码片段中,foo()并非直接通过Base类指针调用(通常认为这种方式才会触发动态绑定),而是从Base的成员函数run()内部调用,但最终执行的却是Derived类的foo()版本,这是为什么?

#include <iostream>

struct Base{
    void run(){
        std::cout << "Base run" << "\n"; 
        foo();
    }
    virtual void foo(){
        std::cout << "Base foo" << "\n"; 
    };
};

struct Derived : Base{
    void foo() override{
        std::cout << "Derived foo" << "\n"; 
    }
};

int main(){
    Derived d;
    Base* ptr = &d;
    ptr->run();
}

程序输出:

Base run
Derived foo

原因解析

核心逻辑是:C++中虚函数的动态绑定,取决于调用该函数的对象的实际类型,和调用发生的位置(基类成员函数内还是外部)无关。

具体拆解过程:

  • 你用Base* ptr = &d;定义的指针,静态类型是Base*,但它指向的对象的实际类型是Derived。
  • 调用ptr->run()时,因为run()不是虚函数,所以直接执行Base类的run()实现(静态绑定)。
  • 但在Base::run()里调用foo()时,这个调用等价于this->foo()——这里的this指针指向的是当前实际对象,也就是Derived实例,所以this的实际类型是Derived*。
  • 由于foo()是虚函数,C++会通过对象内部的虚函数表(vtable),根据this指向的实际对象类型,动态绑定到Derived类的foo()实现。

简单说,只要是虚函数,不管在哪里调用,最终执行哪个版本,只看当前正在操作的对象到底是哪个类的实例。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:27:47