c – 没有虚拟继承的多重继承

我试图理解多重继承,这里是我的代码:

struct A {
  A() {}
  static int n;
  static int increment() { return ++n; }
};
int A::n = 0;

struct B : public A {};
struct C : public A {};
struct D : public B, C {};

int main() {
  D d;
  cout<<d.increment()<<endl;
  cout<<d.increment()<<endl;
}

此代码工作.但是,如果我将increment()更改为非静态,那么它将失败.

我的问题:

为什么编译器抱怨一个非静态版本的increment()的模糊调用,同时满足静态的一个?
>如果我将另一个increment()函数添加到B或C,编译器也会抱怨,甚至声明为静态.为什么?

最佳答案
歧义是什么意思?

编译器抱怨模糊调用,当它不能决定在给定上下文的情况下调用哪个函数调用.所以,为了理解投诉,你必须检查可能存在的歧义.

Why compiler complains ambiguous call of non-static version of increment(), while satisfies with the static one?

根据定义,类的静态函数不依赖于该类的任何实例.这可以称之为A :: increment()(参见,没有实例).

钻石继承的问题不在于编译器不知道要执行哪个代码,而是不知道该提供哪个代码(在D对象中有两个A,一个包含在B中,另一个在C中).

当你使用A的静态函数时,不会隐式传递,所以没有问题;如果您尝试使用非静态函数,那么编译器无法确定这是否应该指向B或C中的A,它是不明确的.

If I add another increment() function to B or C, compiler will complain too, even declared as static. Why?

在这一点上,编译器可以选择B :: increment()和C :: increment(),它应该选哪个?这是模糊的

当你有一个线性层次结构时,它会调用它的“最接近”(将它们隐藏在继承树之下),但这里B和C是两个独立的分支,没有“更好的”分支.

注意:即使B不实现增量,因为A可以调用实际调用A :: increment()的B :: increment().对于C.

转载注明原文:c – 没有虚拟继承的多重继承 - 代码日志