I am trying to understand multiple inheritance, here is my code:
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;
}
This code works. However, if I change increment()
to non-static it will fail.
My questions:
increment()
, while satisfies with the static one?increment()
function to B or C, compiler will complain too, even declared as static. Why?What does ambiguous mean?
A compiler complains of ambiguous calls when it cannot decide which function to call given the context. So, in order to understand the complaints, you have to check what the possible ambiguities could be.
Why compiler complains ambiguous call of non-static version of increment(), while satisfies with the static one?
By definition, a static
function of a class does not depend on any instance of the class. This is emphasized by the fact that you could call it A::increment()
(see, no instance).
The problem of the diamond inheritance is not that the compiler does not know which code to execute, it's that is does not know which this
to provide (there are two A
in your D
object, one contained in B
and one in C
).
When you use a static
function of A
, no implicit this
is passed, so there is no issue; if you try to use a non-static
function, then the compiler cannot decide whether this
should point to the A
in B
or in C
, it's ambiguous.
If I add another increment() function to B or C, compiler will complain too, even declared as static. Why?
At this point, the compiler may choose between B::increment()
and C::increment()
, which should it pick? It's ambiguous.
When you have a linear hierarchy, it calls the "closest" to it (which hides those further down the inheritance tree), but here B
and C
are two independent branches and there is no "better" branch.
Note: even if B
does not implement increment
, since A
does you can call B::increment()
which actually calls A::increment()
. The same goes for C
.
Diamond inheritance: http://www.parashift.com/c++-faq/mi-diamond.html Hiding functions: http://www.parashift.com/c++-faq/hiding-inherited-public.html
This statement:
struct D : public B, C {};
Would create two instances of A
. Compiler needs to know from which instance you intend to call the method. A static
function is nothing but a global function, which is friend to the class - the only requirement is fully-qualified name when caller intents to call it. Static won't play any role in inheritance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With