[英]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: 例如:
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 . 请记住,运行时多态仅适用于指针和引用 。
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.