在C++中没有像Python那样的MRO。如果方法不明确,则是编译时错误。一个方法是否是虚拟的并不影响它,而是虚拟的
继承
在C++标准中描述了该算法。§[class.member.lookup](10.2)。基本上,它将在超类图中找到最接近的明确实现。算法的工作原理如下:
-
假设你想查一个函数
在课堂上
C级
-
查找集
成为一对(
Δ
,
Σ
)代表所有的可能性。
(§10.2/3)
-
那套
Δ
被称为
,这基本上是所有可能的
f
-
那套
Σ
子对象集
,其中包含这些
f
找到的。
-
让
S(f,C)
包括所有
f
using
-ed)英寸
C级
,如果有的话
(§10.2/4)
Î = {f in C};
if (Î != empty)
Σ = {C};
else
Σ = empty;
S(f, C) = (Î, Σ);
-
S(f,C)
(§10.2/5)
,
-
计算
S(f,B)
)
哪里
B类
我
是的基类
.
-
合并每个
)
进入之内
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);
}
-
最后,作为名称解析的结果返回声明集
.
return S(f, C).Î;
-
两个查找集之间的合并(
Δ
1
,
Σ
1
Δ
2
Σ
2
(§10.2/6)
:
-
如果每个班级
1
是中至少一个类的基类
,返回(
2
,
2
).
(反面类似。)
-
否则如果
1
模棱两可的
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.