编译器如何在内部解决C ++中的菱形问题? [英] How does the compiler internally solve the diamond problem in C++?

查看:78
本文介绍了编译器如何在内部解决C ++中的菱形问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

例如:

   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();
   }

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

解决方案

编译器生成的表列出了每个类的所有成员,并具有允许其在任何类的继承链中向上和向下的链接. /p>

当需要查找成员变量时(在您的示例中为权重),编译器从实际的类(在您的情况下为Liger)开始.它在那里找不到权重成员,因此它将上一层移到父类.在这种情况下,有两个,因此它会扫描Tiger和Lion来查找名称重的成员.仍然没有任何热门歌曲,因此现在它需要再上一层,但是它需要做两次,在该级别的每个班级一次.这一直持续到在继承树的某个级别上找到所需的成员为止.如果在任何给定级别上,仅找到一个考虑所有多个继承分支的成员,那么一切都很好;如果找到两个或多个具有所需名称的成员,则它无法决定选择哪个成员,因此会出错.

We know that we can solve the diamond problem using virtual inheritance.

For example:

   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();
   }

When we compile this code we will get an ambiguity error. Now my question is how compiler internally detects this ambiguity problem (diamond problem).

解决方案

The compiler builds tables that list all the members of every class, and also has links that allow it to go up and down the inheritance chain for any class.

When it needs to locate a member variable (weight in your example) the compiler starts from the actual class, in your case Liger. It won't find a weight member there, so it then moves one level up to the parent class(es). In this case there are two, so it scans both Tiger and Lion for a member of name weight. There aren't still any hits, so now it needs to go up one more level, but it needs to do it twice, once for each class at this level. This continues until the required member is found at some level of the inheritance tree. If at any given level it finds only one member considering all the multiple inheritance branches everything is good, if it finds two or more members with the required name then it cannot decide which one to pick so it errors.

这篇关于编译器如何在内部解决C ++中的菱形问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆