Priority of name hiding in C++ inheritance

197 Views Asked by At

Why the call of print() from pointer to base class (Class A) is working and call to print() from Child class object(Class C) is not working?

Statement 1: Will give "print A" as output as since A::print() is a virtual function it will call print() function of Class C which is inherited from A::print(). This will prove that Class C indeed has print() function

Statement 2: This will give compiler error as B::print(int x) will hide A::print().

Statement 3: Will give compilation error. Why?

Probably because print() is still hidden in Class C as Class C is also inheriting B::print(int x). If this is the case then why call from a->print() worked?

Another question: Is there any rule which specifies that B::print(int x) will hide A::print() in the child classes?

class A{
    public:
    virtual void print();
};

void A::print(){
    cout<<"print A\n";
}

class B:public A{
    public:
        void print(int x);
};

void B::print(int x){
    cout<<"print B " << x <<"\n";
}

class C:public B{
};

void funca(A *a){
    a->print();//Statement 1
}

void funcb(B *b){
    //b->print(); Statement 2
}

void funcc(C *c){
    //c->print(); Statement 3
}

int main(){

    C d;
    funca(&d);
    funcb(&d);
    funcc(&d);
}
2

There are 2 best solutions below

3
artm On

Probably because print() is still hidden in Class C as Class C is also inheriting B::print(int x). If this is the case then why call from a->print() worked?

A is base class so there is nothing to hide there, a->print() just works from base class context.

Both B and C hides the original print() function with a different prototype print(int) and so the error as the function is called with wrong prototype (there is no more print() in B or C class)

8
TrebledJ On

Statement 3: Will give compilation error. Why?

For the same reason that b->print() didn't work. This is the error when Statement 2 runs:

In function 'void funcb(B*)':
error: no matching function for call to 'B::print()'
     b->print(); //  Statement 2
              ^
note: candidate: 'void B::print(int)'
 void B::print(int x){
      ^
note:   candidate expects 1 argument, 0 provided

This is the error when Statement 3 runs:

In function 'void funcc(C*)':
error: no matching function for call to 'C::print()'
     c->print(); //  Statement 3
              ^
note: candidate: 'void B::print(int)'
 void B::print(int x){
      ^
note:   candidate expects 1 argument, 0 provided

It's practically the same error, since as you've guessed: C inherits B, whose print function hides A's.

If this is the case then why call from a->print() worked?

Because your reference to C was casted into a pointer to A, as such, exposing A's print function instead of B's. If you do this explicitly, you'd get the same results:

static_cast<A*>(&d)->print();    //  print A
static_cast<B*>(&d)->print();    //  error: no matching function for call to 'B::print()'