Приоритет сокрытия имени в наследовании C ++ - PullRequest
0 голосов
/ 07 января 2019

Почему работает вызов print () из указателя на базовый класс (класс A), а вызов print () из объекта дочернего класса (класс C) не работает?

Оператор 1: выдаст «print A» в качестве вывода, так как A :: print () является виртуальным Функция будет вызывать функцию print () класса C, которая унаследована от A :: print (). Это докажет, что класс C действительно имеет функцию print ()

Заявление 2: Это даст ошибку компилятора, так как B :: print (int x) будет скрывать A :: печать ().

Оператор 3: выдаст ошибку компиляции. Почему?

Возможно, потому что print () все еще скрыт в классе C, поскольку класс 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 голосов
/ 07 января 2019

Оператор 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()'
0 голосов
/ 07 января 2019

Возможно, потому что print () все еще скрыт в классе C, поскольку класс C также наследует B :: print (int x). Если это так, то почему сработал вызов из a-> print ()?

A - это базовый класс, поэтому там нечего скрывать, a->print() просто работает из контекста базового класса.

И B, и C скрывают исходную функцию print() с другим прототипом print(int), поэтому ошибка при вызове функции с неверным прототипом (в B больше нет print() или C класс)

...