繁体   English   中英

在什么情况下不会执行vtable构造?

[英]In which cases does vtable construction not occur?

我注意到代码中由于某种原因没有发生虚拟覆盖。 我正在广泛使用多态性,以便可以使用诸如derived.baseFunc()类的构造,其中baseFunc调用在Derived重写的虚函数。

在哪些情况下不会执行vtable构造并且多态行为变得不可靠?

注意:在一个简单的情况下,一切正常,因此不需要发布代码。

更新 :vtables看起来不错。 似乎存在命名空间的簇f ** k可能是问题所在。 另外,将代码复制粘贴到新文件中并删除名称空间可以解决此问题。

由于没有代码,因此很难确定地说些什么,但是这里有一些疯狂的猜测/选择

  • 您实际上并未覆盖该方法。 您可能认为自己有,但实际上您可能会误会。 例如:

     struct Base{ virtual int f(int); virtual int g() const; virtual ~Base(); }; struct Derived: Base{ int f(); //doesn't override Base::f int g(); //doesn't override Base::g }; 
  • 从构造函数中调用虚拟函数无法按预期工作。 例如,

     struct Base { Base() { f(); } virtual void f() {} virtual ~Base(); }; struct Derived : Base { void f() { cout << "Derived"; } }; Derived d; //Derived will NOT be printed 
  • 某些构造不调用虚拟调度,例如合格的函数调用: ClassName::MethodName()

无论如何,对于任何多态类,vtable总是存在的,所以不要怪编译器:)

任何符合标准的编译器都将具有适当的vtable和多态性。 在正确编写的代码中,总是会发生覆盖。

您需要检查代码中的一些常见编码错误。 例如:

  1. 既然您说过在derived derived.baseFunc()这种情况下不会发生覆盖,所以请检查derived是对象还是引用。 请记住,运行时多态仅适用于指针和引用

  2. 函数签名对于成功覆盖很重要:

     struct Base { virtual void foo (int) {} }; struct Derived : Base { virtual void foo () {} // oops, this `foo` is different than `Base::foo` }; 

如果您的代码正确,则虚函数将按预期工作。 作为一种优化,如果 静态类型 对于此调用的范围具有100%的确定性,则编译器可以将虚拟函数调用转换为常规函数调用,即,可以确定在编译时调用发生在无法更改的编译时已知类型上,因此该函数可能不是唯一的一个具体函数。
在大多数情况下,是这种情况,因为您通过强制转换或作用域解析明确地告诉编译器。 无论如何,它仍然可以按预期工作,没有明显的差异(不同的机器代码和肯定的效率,但行为相同)。

这与vtable的生成无关。 V表无论如何产生(如果编译器使用虚函数表来实现虚拟继承,其中大部分/所有的事,但严格不必 )。

如果它不能按预期工作,则可能(无意中) 隐藏了虚函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM