Вызов переопределенной функции из функции переопределения
Предположим, что у меня есть виртуальная функция foo() в классе B, и мне нужно немного другое поведение в одном из B производных классов, класс D. Можно ли создать функцию переопределения D:: foo() и вызвать B:: foo() оттуда, после обработки специального случая? Вот так:
void D::foo()
{
if (/*something*/)
// do something
else
B::foo();
}
Я не спрашиваю, будет ли это работать, я знаю, что так будет. Я хочу знать, правильно ли это с точки зрения хорошего OOD.
Ответы
Ответ 1
Это отлично. Фактически, канонический способ выполнения некоторых операций - это вызов метода базового класса, а затем делать что угодно (или наоборот). Я думаю о operator=
здесь. Конструкторы обычно работают так же, даже если это немного замаскировано в списке инициализации.
Ответ 2
Да, его полностью нормально, если вы не нарушаете Принцип замещения Лискова.
Ответ 3
Да, это так.
Ответ 4
Я видел, что инфраструктура GUI использует это, чтобы вернуться к реализации по умолчанию базового класса, в которой содержится код, чтобы сигнализировать об ошибках/выдавать исключение/возвращать общее значение.
Ответ 5
Это нормально. Синтаксис, который вы дали, также может использоваться для временного отключения полиморфизма, т.е. Когда вы вызываете метод obj- > B:: foo(), выбирается из класса B независимо от того, является ли foo() виртуальным или нет, и если obj является экземпляром B или нет (это должен быть экземпляр класса, расширяющего B, хотя).
Ответ 6
Да, это то, что ваш компилятор делает для вас каждый раз, когда он генерирует конструктор и деструктор: например, вызывать мать. Я часто полагаюсь на этот "трюк" в моем собственном коде.
Ответ 7
Достаточно назвать базовую реализацию, но при этом условно перемещает вас отдельно от семантики конструктора, в отличие от того, что было предложено в других ответах.
Вы можете запустить хрупкий базовый класс двумя способами:
- Предполагая, что
B::foo()
обеспечивает общее поведение для всей иерархии (т.е. забывание метода не всегда называется)
- Отвратительные проблемы в зависимости от того, что делает
// do something
!
Для полноты позвольте упомянуть симметричный подход к дизайну: Шаблон шаблона (базовая реализация, вызывающая конкретную подчасти)