Подтвердить что ты не робот

Вызов переопределенной функции из функции переопределения

Предположим, что у меня есть виртуальная функция foo() в классе B, и мне нужно немного другое поведение в одном из B производных классов, класс D. Можно ли создать функцию переопределения D:: foo() и вызвать B:: foo() оттуда, после обработки специального случая? Вот так:

void D::foo()
{
  if (/*something*/)
     // do something
  else
     B::foo();
}

Я не спрашиваю, будет ли это работать, я знаю, что так будет. Я хочу знать, правильно ли это с точки зрения хорошего OOD.

4b9b3361

Ответ 1

Это отлично. Фактически, канонический способ выполнения некоторых операций - это вызов метода базового класса, а затем делать что угодно (или наоборот). Я думаю о operator= здесь. Конструкторы обычно работают так же, даже если это немного замаскировано в списке инициализации.

Ответ 2

Да, его полностью нормально, если вы не нарушаете Принцип замещения Лискова.

Ответ 3

Да, это так.

Ответ 4

Я видел, что инфраструктура GUI использует это, чтобы вернуться к реализации по умолчанию базового класса, в которой содержится код, чтобы сигнализировать об ошибках/выдавать исключение/возвращать общее значение.

Ответ 5

Это нормально. Синтаксис, который вы дали, также может использоваться для временного отключения полиморфизма, т.е. Когда вы вызываете метод obj- > B:: foo(), выбирается из класса B независимо от того, является ли foo() виртуальным или нет, и если obj является экземпляром B или нет (это должен быть экземпляр класса, расширяющего B, хотя).

Ответ 6

Да, это то, что ваш компилятор делает для вас каждый раз, когда он генерирует конструктор и деструктор: например, вызывать мать. Я часто полагаюсь на этот "трюк" в моем собственном коде.

Ответ 7

Достаточно назвать базовую реализацию, но при этом условно перемещает вас отдельно от семантики конструктора, в отличие от того, что было предложено в других ответах.

Вы можете запустить хрупкий базовый класс двумя способами:

  • Предполагая, что B::foo() обеспечивает общее поведение для всей иерархии (т.е. забывание метода не всегда называется)
  • Отвратительные проблемы в зависимости от того, что делает // do something!

Для полноты позвольте упомянуть симметричный подход к дизайну: Шаблон шаблона (базовая реализация, вызывающая конкретную подчасти)