Inheritance doesn't have to be "resolved", as you put it, so the question isn't very clear.
The important difference is between ordinary inheritance and virtual inheritance. If you inherit ordinarily, i.e. B : A
, C : A
, then the class D : B, C
has two subclasses of type A
, namely D::B::A
and D::C::A
. On the other hand, if B
and C
inherit virtually from A
, then the ultimate subclass composition will be deferred until you define the final type. That is, B : virtual A
and C : virtual A
themselves each have a virtual subclass A
which would become real if you were to instantiate either B
or C
. On the other hand, if you derive from the classes further, then the most derived class will contain only one subclass of type A
.
Perhaps you may like to consider the analogy with member functions. If each derived class adds a member function of the same name as a base function, you end up with several distinct functions. On the other hand, if the base function is virtual
, then you only ever have one function, which is defined in the most derived class. You still have some sort of function in each intermediate class (assuming the function isn't pure-virtual), but only the final class defines the "active" definition.
Virtual inheritance has an effect on constructors, namely that the virtual-base constructor (i.e. A()
in the example) is called directly by the most derived class, i.e. D
, and not by B
or C
. If you will, this is because only D
"knows" that it contains only one A
-subclass, so it is directly "responsible" for it. B
and C
just hold a virtual placeholder that gives way to the ultimate, most derived class.
Accessing a member function through any base pointer/reference behaves just as expected and is resolved in the usual fashion (i.e. dynamically, in general), but that has nothing to do with virtual inheritance. The actual function lookup may be a bit more complicated as it may involve an extra level of indirection, but that doesn't change anything fundamental.