【问题标题】:virtual table with different parameter types具有不同参数类型的虚拟表
【发布时间】:2015-11-16 11:08:30
【问题描述】:
class Base {
  public:
    virtual void f(float) { cout << "Base::f(float)\n"; }
};

class Derived : public Base {
  public:
    virtual void f(int) { cout << "Derived::f(int)\n"; }
};

int main() {
  Derived *d = new Derived();
  Base *b = d;
  b->f(3.14F);
  d->f(3.14F);
}

据我了解,Derived 类的虚表是:

+-----------------+
| Base::f(float)  |
+-----------------+
| Derived::f(int) |
+-----------------+

但是,这个程序输出:

Base::f(float)
Derived::f(int)

为什么这两个输出不同的结果?我认为bd 应该指向同一个虚拟表。

【问题讨论】:

  • 您到底期望什么?

标签: c++ overriding virtual-functions method-signature


【解决方案1】:

这实际上与 vtables 没有任何关系。在这种情况下,Derived::fnot 覆盖Base::f,它声明了一个隐藏Base::f 的新函数。

您可以使用合格的调用直接在Derived 实例上调用Base::f

d->Base::f(3.14F);

或者您可以使用using 指令公开Base::f

class Derived : public Base {
  public:
    using Base::f;
    virtual void f(int) { cout << "Derived::f(int)\n"; }
};

使用using 指令,intfloat 版本都将被考虑:

d->f(3.14F); //calls Base::f
d->f(3);     //calls Derived::f

C++11 引入了override 说明符来帮助诊断此类问题。如果您进行以下更改:

 void f(int) override { cout << "Derived::f(int)\n"; }

然后 g++ 给出以下错误:

main.cpp:12:18: error: 
    'virtual void Derived::f(int)' marked 'override', but does not override

【讨论】:

  • 我想知道编译器如何为b-&gt;f(3.14F); 工作。我想它应该检查Derived 的vtable,因为f(float) 有可能在d 中被覆盖,如果是这样并且由于Base::f 被隐藏,那么它会找到Base::f() 的地址?对吗?
  • @Deqing 那将是实现它的一种方式。
猜你喜欢
  • 1970-01-01
  • 2014-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-12
  • 2017-02-04
  • 2015-12-20
相关资源
最近更新 更多