В C ++ могут быть переопределены только функции-члены , но не переменные-члены . В результате, когда вы пишете
class Mum : public Dad
{
protected:
int age = 54;
};
C ++ интерпретирует это как «Я знаю, что Dad
уже имеет поле int
с именем age
, значение которого равно 59, но я бы хотел также добавьте другое поле int
с именем age
, значение которого равно 59 и которое относится только к классу Mum
. " Другими словами, вы не заменяете старое значение age
новым; вы объявляете новую переменную, о которой Dad
не знает, что по совпадению имеет то же имя, что и одна из переменных из Dad
.
Теперь, почему это означает, что вы видите значение 59
? Давайте посмотрим на код для Dad
:
class Dad
{
protected:
int age = 59;
public:
void print_age() { cout << age << endl; }
};
В print_age
C ++ видит использование age
и затем должен решить, что делать. Он понятия не имеет, что есть класс Mum
, который будет определен позже, который также независимо создаст protected
int
с именем age
. Скорее, он видит age
, определенный в Dad
, и говорит: «О, это должно быть то, на что ссылается age
», и использует это значение. В результате, когда вы звоните
m.print_age();
, вы видите значение age
в Dad
, а не age
в Mum
. Это потому, что код для print_age
написан в классе Dad
, который ничего не видит в Mum
.
Если вы хотите, чтобы Mum
имел возраст 59 вы можете сделать это вместо этого:
class Mum : public Dad
{
public:
Mum() {
age = 54;
}
};
Здесь конструктор говорит: «когда вы создаете Mum
объект, go находит элемент данных age
и устанавливает его равным 54». Это означает, что есть одна переменная age
, которая по умолчанию равна 59, но явно установлена на 54 в конструкторе Mum
. Теперь, вызов print_age
выведет 54, потому что код для Dad::print_age
просматривает только что установленную переменную age
.
Надеюсь, это поможет!