从派生指针调用虚函数而不支付 vtable 价格

Calling a virtual function from a derived pointer without paying the vtable price

考虑这个简单的例子:

class Base {
    virtual void foo() {};  
};

class Derived: public Base {
    void foo() {}; 
}; 

Base    *b = new Derived;
Derived *d = new Derived;
b->foo();
d->foo();

我的问题是:通过派生 class 指针调用在基 class 中声明为虚函数的成员函数(但在派生 class 中不是)是否使用 (并为 vtable 机制付出代价?在例子中b->foo()使用vtable机制调用Derived::foo(),但是d->foo()?

如果是,如何避免这种行为:当显式使用 Derived 指针时,我想直接调用 Derived::foo() 方法而不支付 vtable 的成本,就好像基 class不存在?

does a call to a member function declared as virtual in a base class (but not in the deverived class)...

我在这里停下来阅读,因为如果Base声明foo为虚拟,Derived只能覆盖fooDerived::foo(据说签名匹配)隐式地 virtual.

以下Derived::foo的定义相同

class Derived: public Base {
  void foo() {}; 
};

class Derived: public Base {
  virtual void foo() {}; 
};

这种机制称为隐式虚拟传播,。理由如下:

10.3 Virtual functions

2 If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list (8.3.5), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.

语法

d->Derived::foo();

将抑制虚拟分派并保证函数 Derived::foo 是被调用的函数,即使存在重写函数也是如此。

这很少是您想要的,但我不能建议替代解决方案,除非您解释为什么要尝试这样做。例如,在给出的代码片段中,根本没有理由 Derived 应该动态分配。你可以这样写:

Derived d;
d.foo();

在这里,编译器肯定知道动态类型是Derived,所以不需要虚拟分派。