C ++继承中名称隐藏的优先级

时间:2019-01-07 10:21:46

标签: c++ inheritance name-hiding

为什么从指针到基类(A类)的print()调用正常,而从子类对象(C类)对print()的调用无效?

声明1:由于A :: print()是虚拟的,因此将给出“ print A”作为输出 函数将调用从A :: print()继承的C类的print()函数。这将证明C类确实具有print()函数

声明2:这将给编译器错误,因为B :: print(int x)将隐藏              A :: print()。

声明3:将给出编译错误。为什么?

可能是因为print()仍隐藏在Class C中,因为Class C也继承了B :: print(int x)。如果是这种情况,那么为什么从a-> print()进行调用有效呢?

另一个问题:是否有任何规则指定B :: print(int x)将A :: print()隐藏在子类中?

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 个答案:

答案 0 :(得分:3)

  

可能是因为print()仍隐藏在Class C中,因为Class C也继承了B :: print(int x)。如果是这种情况,那么为什么从a-> print()进行调用有效呢?

A是基类,因此没有什么可隐藏的,a->print()仅在基类上下文中有效。

BC都用不同的原型print()隐藏了原始的print(int)函数,因此错误的原型调用了该函数的错误(不再存在) print()B类中的C

答案 1 :(得分:1)

  

声明3:将给出编译错误。为什么?

出于同样的原因,b->print()无法正常工作。这是语句2运行时的错误:

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

这是语句3运行时的错误:

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

实际上,这是相同的错误,因为您已经猜到:C继承了B,后者的print函数隐藏了A

  

如果是这种情况,那么为什么要通过a-> print()进行调用呢?

因为这样,您对C的引用被转换为指向A的指针,从而公开了A的打印功能而不是B的打印功能。如果您明确地执行此操作,则会得到相同的结果:

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