>基类具有虚拟方法的对象foo()
>具有多重继承的任意层次结构(虚拟和非虚拟);每个类是Object的子类型;其中一些覆盖foo(),有些不会
>这个层次结构中的一个类X,而不是覆盖foo()
如何在C中的类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.总结
以上是内存溢出为你收集整理的C中的方法分辨率顺序全部内容,希望文章能够帮你解决C中的方法分辨率顺序所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)