An issue about the description of virtual function in the standard

Viewed 117
#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();
}

Consider the above code , the outcome is 1. However , I have doubt to this outcome due to what the standard says:
class.virtual#def:final_overrider

For convenience we say that any virtual function overrides itself. A virtual member function C​::​vf of a class object S is a final overrider unless the most derived class of which S is a base class subobject (if any) declares or inherits another member function that overrides vf.

class.derived#def:inheritance

Members of a base class other than constructors are said to be inherited by the derived class. Constructors of a base class can also be inherited as described in [namespace.udecl].

IIUC, consider the base class subobject of type A in B and in C as A1, A2 respectively. In my example, the most derived class is D, According to the above rules, for class B, the final overrider is A::f which is inherits from A, for class C, the final overrider is C::f which is declared in class C, and for class D, it's derived from B and C, so it will inherit these members from B and C. Since C::f overrides A::f, So according to the rule unless **the most derived class of which S is a base class subobject** (if any) declares or **inherits another member function that overrides vf**, where consider the A1 as S(namely, A1 is the subobject of class D), where D inherits the another member function that overrides vf which is C::f. that means, the final override for the subobject A1 should be C::f, hence , I wonder why the outcome wasn't abc instead for 1?

Another question is:

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

}; 

Both B::f and C::f override the virtual function A::f, but they do not override each other, so which the function does D inherits? or both are inherited by D?

If I miss something, how to read the above rule correctly. Or for the first question, Is the above rule indeed unclear to make misunderstanding?

1 Answers

... A virtual member function C​::​vf of a class object S is a final overrider unless the most derived class of which S is a base class subobject (if any) declares or inherits another member function that overrides vf.

The quoted rule might be defective by being a bit misleading.

It should not be sufficient for vf to be overridden for just any base of type B, but it should be overridden specifically for that base subobject. In your example, there are two base sub objects of type A, one of which has A::f overridden and the other does not.

so which the function does D inherits? or both are inherited by D?

Both are inherited.

Related