没有虚拟继承的多重继承

Deq*_*ing 11 c++ inheritance multiple-inheritance virtual-inheritance

我想了解多重继承,这是我的代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

这段代码有效.但是,如果我increment()改为非静态,它将失败.

我的问题:

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

Mat*_* M. 10

暧昧是什么意思?

当编译器无法决定在给定上下文时调用哪个函数时,编译器会抱怨模糊调用.因此,为了理解投诉,您必须检查可能存在的含糊之处.

为什么编译器抱怨对static()的非静态版本的模糊调用,同时满足静态版本?

根据定义,static类的函数不依赖于类的任何实例.你可以调用它来强调这一点A::increment()(参见,没有实例).

钻石业的问题不在于编译器不知道哪个代码执行,这是不知道哪个this提供(有两个A在你的D对象,包含在一个B,一个在C).

当你使用static函数时A,没有this传递隐式,所以没有问题; 如果你试图使用非static函数,那么编译器无法决定是否this应该指向Ain B或in C,这是不明确的.

如果我向B或C添加另一个increment()函数,编译器也会抱怨,甚至声明为static.为什么?

此时,编译器可以选择B::increment()和之间选择C::increment()哪个?这是模棱两可的.

当你有一个线性的层次,它口中的"最接近"它(其中还隐藏了那些沿着继承树),但在这里BC是两个独立的分支,没有"更好"的分支.

注意:即使B没有实现increment,A也可以调用B::increment()哪些实际调用A::increment().同样的道理C.


Doc*_*sha 9

  1. 它被称为钻石继承问题.你有两个派生自A的类.然后派生自两个类.你有两个版本的非静态void increment().有了静态你有一个.
  2. 因为你可以,但绝不应该覆盖非虚函数,也许你的编译器是严格的或严格的模式.

钻石继承:http://www.parashift.com/c++-faq/mi-diamond.html 隐藏功能:http://www.parashift.com/c++-faq/hiding-inherited-public.html