代码之家  ›  专栏  ›  技术社区  ›  xmh0511

关于标准中虚函数描述的一个问题

  •  0
  • xmh0511  · 技术社区  · 5 年前
    #include <iostream>
    struct A { 
        virtual void f(){
            std::cout<<"1\n";
        } 
    };
    struct B : A {
    
    };
    struct C : A { 
        void f(){
            std::cout<<"abc\n";
        } 
    };
    struct D : B, C { 
    
    }; 
    int main(){
      D mostDerived{};
      D* ptr = &mostDerived;
      B* bptr = ptr;
      A* aptr = bptr;
      aptr->f();
    }
    

    考虑上面的代码, outcome 1 . 然而,我对这一结果表示怀疑,因为该标准规定:
    class.virtual#def:final_overrider

    类对象 最派生的类,其中S是基类子对象 (如有)声明或 继承另一个重写vf的成员函数

    class.derived#def:inheritance

    IIUC,考虑类型的基类子对象 A 在B和B中 C A1 , A2 分别地在我的示例中,派生最多的类是 D ,根据上述规则,上课 B A::f 这是继承自 ,上课 C ,最后一个重写器是 C::f C D ,它是从 B C ,因此它将从中继承这些成员 B C . 自从 C::f 覆盖 A::f ,所以根据规则 unless **the most derived class of which S is a base class subobject** (if any) declares or **inherits another member function that overrides vf** 在哪里考虑 A1 S (即, A1 是类的子对象 ),在哪里 D another member function that overrides vf 那是 . 这意味着,子对象的最终替代 A1 应该是 C::f abc 代替 1. ?

    另一个问题是:

    struct A { 
        virtual void f(){
            std::cout<<"1\n";
        } 
    };
    struct B : A {
      void f(){}
    };
    struct C : A { 
        void f(){}
    };
    struct D : B, C { 
    
    }; 
    

    B::f C::f 重写虚拟函数 A::f ,但它们不会相互重写,因此函数会这样做 D D

    1 回复  |  直到 5 年前
        1
  •  2
  •   eerorika    5 年前

    ... 类对象S的虚拟成员函数C::vf是最终重写器,除非S是基类子对象(如果有)的最派生类声明或继承另一个重写vf的成员函数。

    引用的规则可能有点误导性,因而有缺陷。

    这不应足以满足以下要求: vf 任何 型底 B 那个基础子对象 A ,其中一个 A::f 覆盖,而另一个不覆盖。

    那么D继承哪个函数呢?或者两者都是D继承的?

    两者都是遗传的。