【问题标题】:Virtual function ambiguity solving虚函数歧义求解
【发布时间】:2014-07-30 15:28:24
【问题描述】:

所以在这里我得到了一个下降解释,什么是虚函数以及为什么我们真的需要它,

In C++, what is a virtual base class?

但在我的脑海中仍然存在一个问题,即编译器如何实际解释在多重继承或混合继承的情况下应该使用哪个定义。例如考虑这个例子

class Up {
 public: 
 void func(){
      ...
    } 
};

class Middle_1 : public virtual Up {
 public:
 ...
};

class Middle_2 : public virtual Up {
 public:
 ...
};

class Down : public Middle_1, public Middle_2 {
 public:
 ...
};

在上面的示例代码中,Down 类接收到Up 类的两个定义(即一个来自Middle_1,另一个来自Middle_2)。但是,我们确保在 Middle_1Middle_2 类中使用 virtual 标记,这将消除歧义的情况(因为编译器只会采用一个定义),这就是我的问题所在。

其实我有很多问题,

  • 编译器将如何选择最适合的类?

  • 选择是否在所有条件下都相似?

  • 编译器的智商为零,这不矛盾吗?

提前致谢。

【问题讨论】:

  • Down在内存中的结构如下:{Up}{Middle_1}{Middle_2}{Down}。编译器必须继承自这两个类,因此没有“最适合的类”(我认为这里有些混乱)。选择通常基于您指定继承的顺序,但这可能是实现定义的。编译器智商?
  • 编译器的智商为零。编写它们的人通常智商很高。
  • @Aggieboy:Down 的确切结构布局是实现定义的; C++ 标准没有规定如何实现虚拟基类。我不确定我是否见过编译器用于虚拟继承的特定布局,但我肯定见过{{P}Middle_1}{{P}Middle_2}{Down}{Up} 布局,其中{P} 是指向Up 虚拟基类实例的指针.
  • @AdamRosenfield 我相信它必须在连续的内存中(否则放置 new 将不起作用),即使排序等是实现定义的。我说的主要是g++ 的作用,但我会检查一下。
  • 我只是 C++ 的初学者,只是陷入了这个疑问。我真的不知道这个问题是否真的很愚蠢,但老实说,这是我真正的好奇心。并感谢您重新提出我的问题!有人真的试图理解我的问题,真是太好了。

标签: c++ compiler-construction


【解决方案1】:

整个程序中只有一个Upclass。无需选择任何内容。

也许你想问编译器将如何选择最适合的Up 子对象 表面上每个Middle_1 对象中都有一个Up 子对象,和一个每个Middle_2 子对象中的Up 子对象。编译器需要选择其中一个来与Down 一起使用,对吧?

错了。使用虚拟继承,子对象相对于其所有者而言并不固定。 Middle_1Middle_2 都没有创建自己的 Up 子对象,并且他们事先不知道这些 Up 子对象的位置。他们只知道他们将拥有一个。 有人必须将Up的实例交给他们。

所以编译器会做一些肮脏的把戏。它将为每个Down 对象创建一个单个 Up 子对象,然后告诉Middle_1 部分 Middle_2 部分 em> Down 部分是 他们的 Up 子对象。所以这三个部分都会把那个Up当作自己的,完全不知道它实际上是共享的。

这个方案确实需要一些不平凡的智商来发明,但是每个愚蠢的编译器都能够实现它。

【讨论】:

  • 这对我来说真的很有帮助,也相当令人惊讶。我从来不知道编译器也会执行这种操作。非常感谢您提供这么好的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多