在哪些情况下,vtable结构不会发生?

mos*_*ear 0 c++ vtable

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

在哪些情况下,vtable结构不会发生,多态行为变得不可靠?

注意:对于一个简单的情况,一切正常,因此不需要发布代码.

更新:vtable看起来很好.似乎有一个命名空间的clusterf**k可能是问题.此外,将代码复制粘贴到新文件并删除命名空间可以解决问题.

Arm*_*yan 7

由于没有代码,很难说出某些东西,但这里有一些疯狂的猜测/选项

  • 您实际上没有覆盖该方法.你可能认为你有,但事实上你可能会弄错.例如:

    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
    };
    
    Run Code Online (Sandbox Code Playgroud)
  • 从构造函数中调用虚函数不会像您期望的那样工作.例如,

    struct Base
    {
        Base()
        {
            f();
        }
        virtual void f() {}
        virtual ~Base();
    };
    struct Derived : Base
    {
        void f() { cout << "Derived"; }
    };
    
    Derived d; //Derived will NOT be printed
    
    Run Code Online (Sandbox Code Playgroud)
  • 某些构造不会调用虚拟分派,例如合格的funcion调用: ClassName::MethodName()

在任何情况下,对于任何多态类,vtable总是存在,所以不要责怪编译器:)

  • *从构造函数调用虚函数不会调用虚拟调度机制!*不正确和误导.虚拟调度确实发生,只是它没有做到人们所期望的.被调用的构造函数中的`this`总是指向构造函数的对象,导致调用该类的函数. (2认同)

iam*_*ind 5

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

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

  1. 由于您说过覆盖不是因为derived.baseFunc()某种情况而发生,请检查derived是对象还是引用.请记住,运行时多态性仅适用于指针和引用.

  2. 功能签名对于成功覆盖非常重要:

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

  • 是的,我不知道为什么.这是一个很好的答案 (2认同)