简体   繁体   English

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

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

I've noticed that virtual override is not occurring for some reason in my code. 我注意到代码中由于某种原因没有发生虚拟覆盖。 I'm extensively using polymorphism so that I can use constructs like derived.baseFunc() , where baseFunc calls a virtual function overriden in Derived . 我正在广泛使用多态性,以便可以使用诸如derived.baseFunc()类的构造,其中baseFunc调用在Derived重写的虚函数。

In which cases does vtable construction not occur and polymorphic behavior becomes unreliable? 在哪些情况下不会执行vtable构造并且多态行为变得不可靠?

Note: for a simple case, everything works fine, so code doesn't need to be posted. 注意:在一个简单的情况下,一切正常,因此不需要发布代码。

Update : The vtables look all right. 更新 :vtables看起来不错。 It seems that there's a clusterf**k of namespacing that may be the issue. 似乎存在命名空间的簇f ** k可能是问题所在。 Plus, copy-pasting the code to new file and removing the namespaces fixes the issue. 另外,将代码复制粘贴到新文件中并删除名称空间可以解决此问题。

Since there is no code, it's hard to say something for certain, but here are some wild guesses/options 由于没有代码,因此很难确定地说些什么,但是这里有一些疯狂的猜测/选择

  • You didn't actually override the method. 您实际上并未覆盖该方法。 You may think that you have, but in fact you may be mistaken. 您可能认为自己有,但实际上您可能会误会。 For example: 例如:

     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 }; 
  • Calling of a virtual function from the constructor doesn't work as you'd expect. 从构造函数中调用虚拟函数无法按预期工作。 For example, 例如,

     struct Base { Base() { f(); } virtual void f() {} virtual ~Base(); }; struct Derived : Base { void f() { cout << "Derived"; } }; Derived d; //Derived will NOT be printed 
  • Some constructs don't invoke virtual dispatch, such as qualified funcion calls: ClassName::MethodName() 某些构造不调用虚拟调度,例如合格的函数调用: ClassName::MethodName()

In any case, for any polymorphic class the vtable is always there, so don't blame the compiler :) 无论如何,对于任何多态类,vtable总是存在的,所以不要怪编译器:)

Any conforming compiler will have proper vtable and polymorphism in place. 任何符合标准的编译器都将具有适当的vtable和多态性。 In properly written code, overriding always happens. 在正确编写的代码中,总是会发生覆盖。

You need to check for some common coding mistakes in your code. 您需要检查代码中的一些常见编码错误。 For example: 例如:

  1. Since you said that overriding is not happening for derived.baseFunc() kind of cases, check whether derived is an object or reference. 既然您说过在derived derived.baseFunc()这种情况下不会发生覆盖,所以请检查derived是对象还是引用。 Remember that runtime polymorphism is applicable only via pointers & references . 请记住,运行时多态仅适用于指针和引用

  2. Function signature is important for successful overriding: 函数签名对于成功覆盖很重要:

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

If your code is correct, then virtual functions will work as expected. 如果您的代码正确,则虚函数将按预期工作。 The compiler may, as an optimization, transform virtual function calls into normal function calls if it is 100% certain about the static type that the dynamic type is of "static" nature for the scope of this call, ie it is certain at compile time that the call happens on a compiletime-known type that cannot change, and thus the function cannot possibly be anything else than exactly one concrete function. 作为一种优化,如果 静态类型 对于此调用的范围具有100%的确定性,则编译器可以将虚拟函数调用转换为常规函数调用,即,可以确定在编译时调用发生在无法更改的编译时已知类型上,因此该函数可能不是唯一的一个具体函数。
Most of the time, this is the case because you explicitly tell the compiler either with a cast or scope resolution. 在大多数情况下,是这种情况,因为您通过强制转换或作用域解析明确地告诉编译器。 Regardless, it will still work as expected with no observable difference (different machine code and more efficient for sure, but same behaviour). 无论如何,它仍然可以按预期工作,没有明显的差异(不同的机器代码和肯定的效率,但行为相同)。

This is irrespective of generation of a vtable. 这与vtable的生成无关。 The vtable is generated anyway (if the compiler uses vtables to implement virtual inheritance, which most/all do, but strictly do not have to). V表无论如何产生(如果编译器使用虚函数表来实现虚拟继承,其中大部分/所有的事,但严格不必 )。

If it does not work as expected, you probably hide the virtual function (unintentionally). 如果它不能按预期工作,则可能(无意中) 隐藏了虚函数。

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

相关问题 在堆上分配时,在什么情况下(如果有的话)会发生“自动”清理,而在什么情况下不会发生? - When allocating on the heap, in which cases does “automatic” cleanup occur (if at all) and in which cases does it not? 编译器如何知道vtable中的哪个条目对应于虚函数? - How does the compiler know which entry in vtable corresponds to a virtual function? c++中子类型的对象使用哪个vtable - Which vtable does the object of subtype use in c++ 链接错误:在丢弃的部分中定义的构造 vtable - Linking error: construction vtable defined in a discarded section 没有成员的课堂成语,仅在构造上有什么作用? - Idiom for class with no members which only does anything on construction? cpp - 在构造/销毁期间是否更改了 vtable 指针 - cpp - is vtable pointer being altered during construction/destruction DLL导出的类的vtable布局不正确:要求澄清有关标头和vtable的构造 - Incorrect vtable layout for class exported by DLL: request for clarification regarding headers and vtable construction 在哪些情况下 printf 返回负值? - In which cases does printf return a negative value? 是否有可能将一个对象转发给一个没有在C ++中定义额外变量或vtable的子类? - Is it possible to downcast an object to a subclass which does not define extra variable or vtable in C++? “vtable fixup”是什么意思? - What does “vtable fixup” mean?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM