C中的方法分辨率顺序

前端之家收集整理的这篇文章主要介绍了C中的方法分辨率顺序前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
考虑下面的类层次结构:

>基类具有虚拟方法的对象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++相关文章