Consider the following class hierarchy:
- base class Object with a virtual method foo()
- an arbitrary hierarchy with multiple inheritance (virtual and non-virtual); each class is a subtype of Object; some of them override foo(), some don’t
- a class X from this hierarchy, not overriding foo()
How to determine which method will be executed upon a call of foo() on an object of class X in C++?
(I’m looking for the algorithm, not any specific case.)
There is no MRO in C++ like Python. If a method is ambiguous, it is a compile-time error. Whether a method is virtual or not doesn’t affect it, but virtual inheritance will.
The algorithm is described in the C++ standard §[class.member.lookup] (10.2). Basically it will find the closest unambiguous implementation in the superclass graph. The algorithm works like this:
Suppose you want to look up a function f in class C.
We define a look-up set S(f, C) being a pair of sets (Δ, Σ) representing all possibilities. (§10.2/3)
The set Δ is called the declaration set, which is basically all the possible f‘s.
The set Σ is called the subobject set, which contain the classes that these f‘s are found.
Let S(f, C) include all f directly defined (or
using-ed) in C, if any (§10.2/4):If S(f, C) is empty (§10.2/5),
Compute S(f, Bi) where Bi is a base class of C, for all i.
Merge each S(f, Bi) into S(f, C) one by one.
Finally the declaration set is returned as the result of name resolution (§10.2/7).
The merge between two look-up sets (Δ1, Σ1) and (Δ2, Σ2) is defined as (§10.2/6):
(Similar for the reverse.)
Otherwise, return (Δ1, Σ1 ∪ Σ2)
For example (§10.2/10),
We compute that
and