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

C++代码虚表查询次数分析:this指针与虚函数调用的疑问

#include <iostream>

class Base {
public:
  virtual void Interface() = 0;
  virtual ~Base() {};

protected:
  int Identify() { return SubclassesMustImplement(); }

private:
  virtual int SubclassesMustImplement() = 0;
};

class Derived : public Base {
public:
  void Interface() override { std::cout << Identify() << std::endl; };

private:
  int SubclassesMustImplement() final { return 42; };
};

int main() {
  Derived d;
  Base* b = &d;
  b->Interface();
}
虚表查询次数分析

忽略编译器优化的前提下,这段代码会发生两次虚表查询,具体分析如下:

关于this指针的指向

this指针始终指向实际创建的Derived对象——Base* b = &d只是用基类指针引用派生类对象,对象本身的动态类型还是Derived,不存在“指向Base对象”的情况。

逐步骤拆解虚表查询

  • 第一次查询:b->Interface()
    Interface是虚函数,基类指针调用虚函数时必须通过虚表查询,找到Derived::Interface的函数地址,这是第一次虚表查询。

  • 第二次查询:Base::Identify()中调用SubclassesMustImplement()

    1. Identify()是非虚函数,编译阶段就能确定调用Base::Identify(),这里不需要虚表查询。
    2. 但SubclassesMustImplement()是纯虚函数,尽管Derived中用final标记了重写版本,在忽略优化的情况下,标准要求虚函数调用必须通过虚表查询(final只是禁止进一步派生,不强制跳过虚表),因此这里会触发第二次虚表查询,找到Derived::SubclassesMustImplement()的地址。

优化场景补充

如果编译器开启了优化(比如-O2),第二次虚表查询可能被优化掉:因为final标记让编译器可以确定Derived是该函数的最终实现类,直接静态绑定到Derived::SubclassesMustImplement(),无需查询虚表。但题目要求忽略优化,所以按两次查询计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 04:20:33