【问题标题】:multiple inheritance without virtual inheritance没有虚拟继承的多重继承
【发布时间】:2014-10-12 04:15:12
【问题描述】:
我正在尝试理解多重继承,这是我的代码:
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() 的调用模棱两可,而静态版本却满足?
- 如果我在 B 或 C 中添加另一个
increment() 函数,编译器也会报错,甚至声明为静态。为什么?
【问题讨论】:
标签:
c++
inheritance
multiple-inheritance
virtual-inheritance
【解决方案1】:
模棱两可是什么意思?
当编译器无法根据上下文决定调用哪个函数时,它会抱怨不明确的调用。因此,为了了解投诉,您必须检查可能存在的歧义。
为什么编译器抱怨非静态版本的增量()调用模棱两可,而静态版本却满足?
根据定义,一个类的static 函数不依赖于该类的任何实例。您可以将其称为A::increment()(请参阅,没有实例)这一事实强调了这一点。
菱形继承的问题不是编译器不知道要执行哪个代码,而是不知道要提供哪个this(你的里面有两个A D 对象,一个包含在B 中,一个包含在C 中)。
当你使用A的static函数时,没有隐式传递this,所以没有问题;如果您尝试使用非static 函数,则编译器无法确定this 是否应该指向B 或C 中的A,这是不明确的。
如果我向 B 或 C 添加另一个 increment() 函数,编译器也会报错,甚至声明为静态。为什么?
此时,编译器可能会在B::increment() 和C::increment() 之间进行选择,它应该选择哪个?模棱两可。
当你有一个线性层次结构时,它会调用“最接近”的层次(将那些隐藏在继承树的更下方),但这里 B 和 C 是两个独立的分支,没有“更好”的分支.
注意:即使B 没有实现increment,因为A 你可以调用B::increment(),它实际上调用了A::increment()。 C 也是如此。
【解决方案3】:
此声明:
struct D : public B, C {};
将创建两个A 实例。编译器需要知道您打算从 哪个 实例调用该方法。 static 函数只不过是一个全局函数,它是类的朋友——当调用者意图调用它时,唯一的要求是完全限定的名称。静态不会在继承中发挥任何作用。