На своем рабочем месте я пытался представить больше привычек разработки Agile / XP. Непрерывный дизайн - это то, что я чувствовал больше всего сопротивления на данный момент. Возможно, я не должен был формулировать это как «давайте соберем всю команду архитекторов и застрелим их» ...;)
Поведение правильное. Всякий раз, когда вы объявляете свою функцию «виртуальной», вы инструктируете компилятор сгенерировать виртуальный вызов вместо прямого вызова этой функции. Всякий раз, когда вы переопределяете виртуальную функцию в классе-потомке, вы указываете поведение этой функции (вы не меняете режим доступа для тех клиентов, которые полагаются на интерфейс «родительского»).
Изменение режима доступа для виртуального функция в классе-потомке означает, что вы хотите скрыть ее от тех клиентов, которые напрямую используют класс-потомок (которые полагаются на «дочерний» интерфейс).
Рассмотрим пример:
void process(const A* object) {
object->func();
}
функция «process» полагается на родительский интерфейс. Ожидается, что он будет работать с любым классом, открытым производным от A. Вы не можете публично наследовать B от A (говоря "
Это четко определенное поведение. Если бы a
был B *
, это не компилировалось. Причина в том, что доступ к члену разрешается компилятором статически, а не динамически во время выполнения. Во многих книгах по C ++ предлагается избегать такого кодирования, потому что это сбивает с толку менее опытных программистов.
Ну, вы вызываете A :: func ()
, который является общедоступным
, хотя в объекте B
он переопределен Автор B :: func ()
. Это общий шаблон со следующими последствиями:
func
не предназначен для вызова на производных B
объектах
func
не может быть переопределен в классах, производных от B