Наследование полей и методов
class a{
public:
int y;
void f(){cout<<6;}
};
class b: public a{
public:
int y;
void f(){cout<<7;}
};
Почему можно делать функции и переменные с одинаковыми именами, как у родительского класса? То есть почему в наследнике не возникает конфликт имен, ведь в нем присутствуют уже все эти методы и поля родительского?
Ответы (1 шт):
Имя некоторой сущности — того же члена y, как просто y — это сокращенная форма, когда очевиден контекст. На самом деле используется полностью квалифицированное имя, которое включает то, к какому классу и какому объекту оно относится. Вас ведь совершенно не смущает, что могут быть два объекта одного класса с одинаковыми членами? потому что вы не используете имя члена само по себе, а присовокупляете к нему имя объекта или указатель на него.
Так и в вашем примере полное имя включает имя класса. При этом в классе-потомке происходит сокрытие имени из предка, в том смысле, что обращение по короткому имени y приводит к обращению к члену в текущем контексте, члену класса-потомка.
Могут быть достаточно закрученные наследования, когда придется указывать в имени не один класс. Например, в приведенном ниже примере с множественным наследованием для обращения к члену A надо указать, к члену какого именно A обращение :)
struct A
{
int x;
void out() { cout << x << endl; }
};
struct B: public A
{
int x;
void out() { cout << x << endl; }
};
struct C: public A
{
int x;
void out() { cout << x << endl; }
};
struct D: public B, public C
{
int x;
void out() { cout << x << endl; }
};
int main(int argc, char * argv[])
{
D d;
d.C::x = 0;
d.B::x = 1;
d.C::A::x = 2;
d.B::A::x = 3;
d.B::A::out();
d.C::A::out();
d.B::out();
d.C::out();
}
P.S. Ау, гуру стандартов! Обнаружил, что приведенный выше код на ура компилируется Visual C++, но не хочет компилироваться, например, G++. Кто неправ? Лично я никакой неоднозначности не вижу — полностью квалифицированные имена различны, какая уж тут неоднозначность?...