#c #inheritance
#c #наследование
Вопрос:
Я определил абстрактный интерфейс, состоящий из трех классов:
class rendering_context {…}
class window : public rendering_context {…}
class offscreen : public rendering_context {…}
Это позволяет различным клиентским объектам игнорировать тип контекста рендеринга, в котором они находятся. Пока все хорошо.
Затем я определил конкретные реализации:
class sdl::window : public window {…}
class sdl::offscreen : public offscreen {…}
Все это работает так, как ожидалось, и клиентские классы довольны, не имея ни малейшего представления о том, основаны ли они на экране / вне экрана / SDL или нет.
Мое замешательство:
Теперь у меня есть специфичная для SDL функциональность, которая применяется во всех контекстах рендеринга, то есть не только в одном или другом из sdl::window
or sdl::offscreen
.
Это говорит о том, что класс sdl::rendering_context
должен быть где-то извлечен, но как мне включить это в иерархию классов?
Если я создам конкретные классы следующим образом:
class sdl::window : public window, public sdl::rendering_context {…}
class sdl::offscreen : public offscreen, public sdl::rendering_context {…}
И предполагая sdl::rendering_context
, что наследуется от rendering_context
then разве я не унаследовал от rendering_context
twice неявно? Делает ли это тот факт, что rendering_context
в данном случае это абстрактный базовый класс без членов и нескольких чисто виртуальных функций, это нормально?
Это то же самое, что и проблема с бриллиантами? Похоже, что это может быть, но разница в том, что нет никакой двусмысленности в отношении того, какой метод базового класса вызывать: они чисто виртуальные, и это, безусловно, будет конкретная реализация в нижней части иерархии, которая выполняется на практике.
[Примечание: Ни одно из моих объявлений классов на самом деле не похоже на приведенное выше, это просто для иллюстрации иерархии. Текущий код компилируется и работает, он просто дублирует некоторые функции.]
Комментарии:
1. Прочитав несколько советов по лучшей практике, возможно, это неправильный вопрос? Должен ли я вместо этого повторно использовать
sdl::rendering_context
код через композицию и оставить иерархию классов исключительно для определения интерфейсов?2. Этот вопрос больше подходит для programmers.stackexchange.com .
3. Спасибо, да, я согласен. Написав вопрос, я понимаю, что это больше касается моего общего подхода к определению интерфейса и повторному использованию кода, а не конкретной технической проблемы.
4. Вот переделка вопроса о программистах StackExchange: programmers.stackexchange.com/questions/246273 /…
Ответ №1:
И если предположить, что sdl ::rendering_context наследуется от rendering_context, то разве я не унаследовал от rendering_context дважды неявно?
Если это проблема, вы можете рассмотреть виртуальное наследование, в котором rendering_context
используется общий базовый класс. Если вы хотите сделать это:
class window : public virtual rendering_context {...}
class offscreen : public virtual rendering_context {...}
Комментарии:
1. Понял, да, это работает, спасибо. Знаете ли вы, есть ли последствия для производительности виртуального базового класса, когда он чисто виртуальный?