编译器如何在内部解决C++中的菱形问题?

amo*_*mod 11 c++ virtual multiple-inheritance diamond-problem

我们知道我们可以使用虚拟继承来解决钻石问题.

例如:

   class Animal // base class
   {
     int weight;
     public:
     int getWeight() { return weight;};
   };
   class Tiger : public Animal { /* ... */ }; 
   class Lion : public Animal { /* ... */ };
   class Liger : public Tiger, public Lion { /* ... */ }; 
   int main()
   {
     Liger lg ;
     /*COMPILE ERROR, the code below will not get past
     any C++ compiler */
     int weight = lg.getWeight();
   }
Run Code Online (Sandbox Code Playgroud)

当我们编译这段代码时,我们会得到一个模糊错误.现在我的问题是编译器内部如何检测这种模糊问题(钻石问题).

Mig*_*uel 5

编译器构建的表列出了每个类的所有成员,并且还具有允许它在任何类的继承链中上下移动的链接。

当需要查找成员变量(示例中的权重)时,编译器从实际类(在您的例子中为 Liger)开始。它在那里找不到权重成员,因此它会向上移动一级到父类。在本例中,有两个,因此它会扫描 Tiger 和 Lion 来查找名称权重的成员。仍然没有任何命中,所以现在需要再升一级,但需要执行两次,该级别的每个班级一次。这将继续下去,直到在继承树的某个级别找到所需的成员。如果在任何给定级别,考虑到所有多重继承分支,它只找到一个成员,那么一切都很好,如果它找到两个或多个具有所需名称的成员,那么它无法决定选择哪一个,因此会出错。