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

通过子类对象直接调用虚方法是否永远不会使用vtable?

问题分析与解答

示例代码

#include <iostream>
#include <array>

struct Base
{
    virtual float getValue() { return 1.0f; }
};

struct Derived : Base
{
    float getValue() override { return 2.0f; }
};

inline void test(Base *obj) {
    std::cout << obj->getValue() << std::endl;
}

int main()
{
    Derived d;
    test(&d);
    float value = d.getValue();
    std::cout << value << std::endl;
}

关于float value = d.getValue();的编译方式

是的,这个调用永远不会通过vtable(虚表),和调用非虚函数的机制本质一致。

原因很明确:这里的d是Derived类型的具体对象实例,不是基类指针或引用。在编译阶段,编译器可以100%确定这个对象的静态类型和动态类型完全一致,不存在多态的可能性——不可能出现d实际是其他派生类对象的情况。因此编译器会直接将调用解析为Derived::getValue(),生成直接函数调用的机器指令,完全不需要在运行时去虚表中查找函数地址。

只有当调用虚函数的是基类指针或引用时,因为其动态类型可能和静态类型不一致(比如基类指针指向派生类对象),编译器无法在编译期确定要调用的函数,这时候才会通过vtable做运行时的函数地址查找。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 15:14:55