Приоритет сокрытия имени в наследовании C++
Почему вызов print () из указателя на базовый класс (класс A) работает, а вызов print () из объекта дочернего класса (класс C) не работает?
Оператор 1: выдаст "print A" в качестве вывода, так как A::print() является виртуальной функцией, она вызовет функцию print () класса C, которая унаследована от A::print(). Это докажет, что класс C действительно имеет функцию print ()
Утверждение 2: Это даст ошибку компилятора, так как B::print(int x) скроет A::print().
Утверждение 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 ответа
Возможно, потому что print() все еще скрыт в классе C, поскольку класс C также наследует B::print(int x). Если это так, то почему сработал вызов из a->print()?
A
это базовый класс, так что там нечего скрывать, a->print()
просто работает из контекста базового класса.
И то и другое B
а также C
скрывает оригинал print()
функция с другим прототипом print(int)
и так ошибка как функция вызывается с неверным прототипом (больше нет print()
в B
или же C
учебный класс)
Утверждение 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
"S.
Если это так, то почему сработал вызов из a->print()?
Потому что ваша ссылка на C
был брошен в указатель на A
как таковой, разоблачающий A
Функция печати вместо B
"S. Если вы сделаете это явно, вы получите те же результаты:
static_cast<A*>(&d)->print(); // print A
static_cast<B*>(&d)->print(); // error: no matching function for call to 'B::print()'