Can someone please explain the reason behind input in each line ?
Class A {
bool f(A* a) { return true; }
}
class B : public A {
bool f(B* b) { return false; }
}
void f() {
A* a = new A();
A* ab = new B();
B* b = new B();
a->f(a); a->f(ab); a->f(b); // true, true, true
ab->f(a); ab->f(ab); ab->f(b); // true, true, true
b->f(a); b->f(ab); b->f(b); // error, error, false
}
B
has two non-virtual methods with the same name: bool f(A*)
and bool f(B*)
.
Normally, these would be overloads; but since one was inherited from a base class, it's hidden by the latter. It's still accessible, it just needs some special syntax to call it, for example:
B b;
B* param;
b.f(param); // calls B::f(B*)
b.B::f(param); // same
b.A::f(param); // calls the hidden A::f(A*)
So:
a->f(a); a->f(ab); a->f(b);
This one is easy: a
is of type A*
, so A::f(A*)
will be called and argument of type B*
will be converted to A*
.
ab->f(a); ab->f(ab); ab->f(b);
Same thing happens, since ab
is also of type A*
.
b->f(a); b->f(ab);
These can't work since b
is of type B*
and b->f
can only refer to B::f(B*)
(A::f
is hidden). You can't implicitly convert from A*
to B*
.
You can mention the hidden method explicitly, though:
b->A::f(a); b->A::f(ab);
And the last works, simply calls B::f(B*)
:
b->f(b);
Remarks:
It doesn't matter here whether the functions are virtual or not. They have different argument types, so one can't override another. One can only hide the other.
C++ allows covariant return types (you might want to have virtual A* foo()
in A
and virtual B* foo()
in B
if the args match). C++ doesn't allow covariant or contravariant argument types, though.