Reputation: 65
I was going through this Book and I can't wrap my head around this:
if B::f(int)
hides A::f()
, why does pa1->f();
not give an error?
Doesn't name hiding mean that, the function f()
doesn't exist in class B
? And if pa1
points to an object of class B
then pa1->f();
should result in an error just as b.f()
does!
Please explain this, as I can't understand it through the book! Thanks in advance!
#include <iostream>
using namespace std;
struct A {
virtual void f() { cout << "Class A" << endl; }
};
struct B: A {
void f(int) { cout << "Class B" << endl; }
};
struct C: B {
void f() { cout << "Class C" << endl; }
};
int main() {
B b; C c;
A* pa1 = &b;
A* pa2 = &c;
// b.f();
pa1->f();
pa2->f();
}
Upvotes: 1
Views: 86
Reputation: 316
The call pa1->f(); is first routed to object of type A, since pa1 is a pointer to that type. The virtual keyword would re-route the call to type B if there was a function that matches the exact(!!) signature of the call. Since there is no such function in type B, the type A function is executed.
What I mean is that in this case the functions do not "hide" each other because the signature differs. [f(void) vs. f(int)]
EDIT: To be more clear. f(int) and f(void) are two completely different functions. As different as f(void) to g(int) would be.
Upvotes: 1
Reputation: 254431
if
B::f(int)
hidesA::f()
, why doespa1->f();
not give an error?
Because pa1
points to A
, and A
has a member called f
which can be called like that. In this context, any other class (including B
) is irrelevant.
Doesn't name hiding mean that, the function
f()
doesn't exist in classB
?
No. It means that, in the context of B
, the only function called f
that can be found by unqualified lookup is B::f
. It doesn't remove f
from any other context, or prevent it from being found by qualified lookup such as b.A::f()
.
And if
pa1
points to an object of classB
thenpa1->f();
should result in an error just asb.f()
does!
The dynamic type is B
, so that's the type used (at run time) to call virtual functions. Non-virtual functions are selected by the compiler according to the static type, which is A
. In general, the compiler doesn't know the dynamic type; all it knows is that the pointer points to an A
or some unknown derived class.
Upvotes: 1
Reputation: 55395
It would be an error if you tried to call f()
from scope of B
. But, you're calling it through a pointer to base class. The name lookup and overload resolution is done based on the static type of the object, A*
in this case. From there, f()
is visible.
Upvotes: 2