Question

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();
}
Was it helpful?

Solution 2

if B::f(int) hides A::f(), why does pa1->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 class B?

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 class B then pa1->f(); should result in an error just as b.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.

OTHER TIPS

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top