Наследование С++ и функция переопределения
В С++ функция-член базового класса переопределяется своей производной функцией класса с тем же именем, , даже если ее прототип (количество параметров, тип и константа) отличается? Я предполагаю, что это глупый вопрос, поскольку многие веб-сайты говорят, что прототип функции должен быть таким же, чтобы это произошло; но почему код ниже не компилируется? Я считаю, что это очень простой случай наследования.
#include <iostream>
using std::cout;
using std::endl;
class A {};
class B {};
class X
{
public:
void spray(A&)
{
cout << "Class A" << endl;
}
};
class Y : public X
{
public:
void spray(B&)
{
cout << "Class B" << endl;
}
};
int main()
{
A a;
B b;
Y y;
y.spray(a);
y.spray(b);
return 0;
}
GCC выбрасывает
error: no matching function for call to `Y::spray(A&)'
note: candidates are: void Y::spray(B&)
Ответы
Ответ 1
Термин, используемый для описания этого, "скрывается", а не "переопределяет". Член производного класса по умолчанию сделает любые члены базовых классов с тем же именем недоступными, независимо от того, имеет ли они одну и ту же подпись. Если вы хотите получить доступ к элементам базового класса, вы можете вывести их в производный класс с объявлением using
. В этом случае добавьте следующее в class Y
:
using X::spray;
Ответ 2
Это так называемое "укрытие": Y::spray
скрывает X::spray
.
Добавить с помощью директивы:
class Y : public X
{
public:
using X::spray;
// ...
};
Ответ 3
Классы являются областями, а область класса вложен в ее родительскую. У вас точно такое же поведение с другими вложенными областями (пространства имен, блоки).
Что происходит, когда поиск по имени ищет определение имени, он смотрит в текущем пространстве имен, затем в пространстве имен enlobing и так далее, пока не найдет одно определение; затем поиск останавливается (что без учета усложнений, вызванных зависимым от аргумента поиска имени - частью правил, которая позволяет использовать функцию, определенную в пространстве имен одного из своих аргументов).