0

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

语句 1:将给出“print A”作为输出,因为 A::print() 是一个虚函数,它将调用 C 类的 print() 函数,该函数继承自 A::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);
}
4

2 回答 2

3

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

A是基类,所以没有什么可隐藏的,a->print()只适用于基类上下文。

两者都B隐藏Cprint()具有不同原型的原始函数,print(int)因此使用错误的原型调用函数时的错误(print()BC类中没有更多)

于 2019-01-07T10:27:50.440 回答
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

这实际上是相同的错误,因为您已经猜到了:Cinherits B,其print功能隐藏了A's。

如果是这种情况,那么为什么从 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()'
于 2019-01-07T10:35:02.813 回答