我想了解多重继承,这是我的代码:
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()
函数,编译器也会抱怨,甚至声明为静态。为什么?答案 0 :(得分:10)
含糊不清是什么意思?
如果编译器在给定上下文时无法决定调用哪个函数,则会抱怨模糊调用。因此,为了理解投诉,您必须检查可能存在的含糊之处。
为什么编译器抱怨对static()的非静态版本的模糊调用,同时满足静态版本?
根据定义,类的static
函数不依赖于类的任何实例。您可以将其称为A::increment()
(请参阅,没有实例)。
钻石继承的问题不在于编译器不知道要执行哪个代码,而是它不知道要提供哪个this
(有A
个对象中的两个D
,其中一个包含在B
中,另一个包含在C
中。
当您使用static
A
函数时,没有传递隐式this
,因此没有问题;如果您尝试使用非static
函数,则编译器无法确定this
是否应指向A
或B
中的C
,它& #39;暧昧。
如果我向B或C添加另一个increment()函数,编译器也会抱怨,甚至声明为static。为什么呢?
此时,编译器可以在B::increment()
和C::increment()
之间进行选择,它应该选择哪个?它含糊不清。
当你有一个线性层次结构时,它会调用&#34;最接近的&#34;它(隐藏在继承树下面的那些),但是这里B
和C
是两个独立的分支,没有&#34;更好的&#34;分支。
注意:即使B
未实现increment
,自A
起,您也可以致电B::increment()
实际调用A::increment()
。 C
也是如此。
答案 1 :(得分:9)
钻石继承:http://www.parashift.com/c++-faq/mi-diamond.html 隐藏功能:http://www.parashift.com/c++-faq/hiding-inherited-public.html
答案 2 :(得分:2)
本声明:
struct D : public B, C {};
将创建A
的两个实例。编译器需要从中知道您打算调用该方法的实例。 static
函数只是一个全局函数,它是类的朋友 - 当调用者打算调用它时,唯一的要求是完全限定名。静态不会在继承中扮演任何角色。