I know there have been many post about diamond problem, one of it: Why do you reduce multiple inheritance to the diamond problem?. But I'm not asking what it is or what is the solution of the problem. Also I'm not asking why multiple inheritance is bad. What I don't understand is, why is it a "problem"? Consider:
struct A {};
struct B : A {
virtual void f() {}
};
struct C : A {
virtual void f() {}
};
struct D : B, C {};
I know the code about can't compile, as "diamond problem" said, D
doesn't know which version of f()
(B
? C
?) should call. What I don't understand is, what assumptions/rules apply at here so that D is expected to select either one method only? Why the result isn't naturally just "d->f()
means calls both B.f()
and C.f()
sequentially"? Why must D
require to select either one?
Another scenario:
struct A {
virtual void f() {}
};
struct B : A {};
struct C : A {};
struct D : B, C {};
I know it would not compile. But what I don't understand is, why isn't
d->f();
just naturally "D
call A
's f()
" once? What is the "ambiguous" thing here? Why must I assume d->f()
would logically call A
's f()
twice at here?
Note: I'm not asking why is multiple inheritance is bad like this: Is there any "real" reason multiple inheritance is hated?
While multiple inheritance has some problems, the problems seems do have solutions: e.g.: if both B
and C
has a class member name
, a language designer can design some syntax to excess like this: d->B::name
or d->C::name
. And I believe programmers have their rights to choose or refuse using multiple inheritance. What I don't understand is, why does a "problem" having solutions called a "problem"?
f
does one specific thing, once (in different ways according to the type). IfB.f
andC.f
are called sequentially, it will happen twice, yeah? – Karl Knechtel Aug 15 '23 at 08:07D::f()
, the compiler knew you wanted that one... but if you didn't, it didn't know whichf()
isD::f()
,... – Justin Time - Reinstate Monica Aug 15 '23 at 17:39public B,public C
and the compiler knows to runB::f()
beforeC::f()
. Declarepublic C,public B
instead if you want the opposite. Or overridef()
if you want something custom. Granted it's bound to cause some unexpected slip-ups, but what's one more gotcha in a language that's already loaded with gotchas? – aroth Aug 16 '23 at 05:05e
where you want the opposite call order? Solving a function-level "problem" at the class-level seems a bad move. – Damien_The_Unbeliever Aug 16 '23 at 07:39