考虑下面的类层次结构:
>基类具有虚拟方法的对象foo()
>具有多重继承的任意层次结构(虚拟和非虚拟);每个类是Object的子类型;其中一些覆盖foo(),有些不会
>这个层次结构中的一个类X,而不是覆盖foo()
(我正在寻找算法,没有任何具体情况.)
解决方法
C中没有像MRO那样的MRO.如果一个方法是模糊的,那么这是一个编译时错误.一个方法是否是虚拟的不影响它,但虚拟继承会.
该算法在C标准§[class.member.lookup](10.2)中描述.基本上它将在超类图中找到最接近的明确的实现.该算法的工作原理如下:
假设你想在C类中查找一个函数f.
>我们定义一个查找集合S(f,C),它是一组表示所有可能性的集合(Δ,Σ). (§10.2/ 3)
>集合Δ称为声明集,这基本上都是可能的f.
>集合Σ被称为子对象集,它包含找到这些f的类.
>让S(f,C)包括C中直接定义(或使用ed)的所有f(如果有的话)(§10.2/ 4):
Δ = {f in C}; if (Δ != empty) Σ = {C}; else Σ = empty; S(f,C) = (Δ,Σ);
>如果S(f,C)为空(§10.2/ 5),
>计算S(f,Bi)其中Bi是C的基类,对于所有i.
将每个S(f,Bi)逐个合并成S(f,C).
if (S(f,C) == (empty,empty)) { B = base classes of C; for (Bi in B) S(f,C) = S(f,C) .Merge. S(f,Bi); }
>最后,声明集作为名称解析的结果返回(§10.2/ 7).
return S(f,C).Δ;
>两个查找集合(Δ1,Σ1)和(Δ2,Σ2)之间的合并定义为(§10.2/ 6):
>如果Σ1中的每个类都是Σ2中至少一个类的基类,则返回(Δ2,Σ2).
(反之亦然)
>否则如果Δ1≠Δ2,则返回(模糊,Σ1∪Σ2).
>否则返回(Δ1,Σ1∪Σ2)
function Merge ( (Δ1,Σ1),(Δ2,Σ2) ) { function IsBaSEOf(Σp,Σq) { for (B1 in Σp) { if (not any(B1 is base of C for (C in Σq))) return false; } return true; } if (Σ1 .IsBaSEOf. Σ2) return (Δ2,Σ2); else if (Σ2 .IsBaSEOf. Σ1) return (Δ1,Σ1); else { Σ = Σ1 union Σ2; if (Δ1 != Δ2) Δ = ambiguous; else Δ = Δ1; return (Δ,Σ); } }
例如(§10.2/ 10),
struct V { int f(); }; struct W { int g(); }; struct B : W,virtual V { int f(); int g(); }; struct C : W,virtual V { }; struct D : B,C { void glorp () { f(); g(); } };
我们计算
S(f,D) = S(f,B from D) .Merge. S(f,C from D) = ({B::f},{B from D}) .Merge. S(f,W from C from D) .Merge. S(f,V) = ({B::f},{B from D}) .Merge. empty .Merge. ({V::f},{V}) = ({B::f},{B from D}) // fine,V is a base class of B.
和
S(g,D) = S(g,B from D) .Merge. S(g,C from D) = ({B::g},{B from D}) .Merge. S(g,W from C from D) .Merge. S(g,V) = ({B::g},{B from D}) .Merge. ({W::g},{W from C from D}) .Merge. empty = (ambiguous,{B from D,W from C from D}) // the W from C is unrelated to B.