Я предполагаю, что вы хотели объявить целочисленное поле a
в классе Foo
.
Ответ на ваш вопрос связан с понятиями «переопределение» и «сокрытие», как это делают другиеуказал.Другой способ объяснить это состоит в том, что для переменных-членов не существует такого понятия, как «динамическая диспетчеризация».Это означает, что если вы обращаетесь к члену определенного объекта, система проверяет во время выполнения , какой элемент вы имеете в виду, просматривая иерархию классов.
Итак, при вызовеметод f.addFive
, во время выполнения система увидит, что ваш объект на самом деле Bar
, а не Foo
, и поэтому возьмите функцию addFive
, которую вы определили в классе Bar
.
Этого не происходит с переменными-членами: вы обращаетесь к f.a
в своем операторе печати, и во время компиляции решается, что прямо здесь вы хотите получить доступ к полю a
, объявленному в классеFoo
там - и вот, это то, что произойдет во время выполнения.
Теперь, причина , что отсутствует динамическая диспетчеризация для доступа к переменной-члену, - это производительность: это будеточень дорого обходить всю логику «посмотрите, что это за объект на самом деле» каждый раз, когда вы просто хотите добавить какое-то значение в переменную-член.