LINUX.ORG.RU

C++ как правильно наследовать дружбу...

 


0

2

Понятно что дружбу наследовать нельзя и не надо. И если хочется, то значит что-то не так. Но я не вкуриваю что не так.

Есть доставшийся мне проект. В нем есть класс UI который отвечает за интерфейс, его логику. Есть абстрактный класс Renderer который отвечает за то чтобы это рисовать, и есть наследники AaaRenderer и BbbRenderer которые знают как это все рисовать через фреймворки Aaa и Bbb.

Для того чтобы рисовать UI, надо иметь доступ к его кишкам. Перечислять всех наследников Renderer в качестве друзей UI кажется идейно неправильным… Вдруг появиться еще Ccc.

Проложим что в Renderer есть защищенные атрибуты internal1 и internal2. Вот как правильно к ним организовать доступ из AaaRendrer и BbbRender?

★★★

Вот блин…

Написал, и сразу понял… Надо Renderer сделать френдом UI и добавить в оный Renderer аксессоры для добывания internal1 и interlal2

Но раз кто-то стал за этой темой следить, то не буду удалять… Может и другие мысли будут.

shaplov ★★★
() автор топика
Ответ на: комментарий от panter_dsd

А ты уверен, что Ccc появится? Может, не мучать моск и зафрейндить оба класса?

Не уверен… Но как-то очень не аккуратно получается… Не приносит чувства удовлетворения…

shaplov ★★★
() автор топика

почему не сделать Renderer наследником UI? то есть UI сделать базовым классом

ведь UI это сферический интерфейс в вакууме, интерфейс как идея, а Renderer - его бренное воплощение, получается

а уже от Renderer наследовать отрисовщиков на конкретных библиотеках

anonymous
()

Вариантов множество и у всех есть свои достоинства и недостатки. От грязных трюков, помогающих получить доступ к внутренностям объекта ты никак не защитишься, потому что это C++. А вот оформить код так, чтобы было более очевидно к чему та или иная сущность имеет доступ в принципе реально.

Можно воспользоваться одной из следующих идиом:

Можно сделать внутренний класс Renderer::Interface, от которого наследовать AaaRenderer и BbbRenderer. Внутренний класс имеет доступ ко всем приватным членам внешнего, поэтому его можно использовать как интерфейс.

m0rph ★★★★★
()

Для того чтобы рисовать UI, надо иметь доступ к его кишкам.

Не надо. Renderer должен предоставлять API достаточное для рисования чего угодно.

zx_gamer ★★★
()

Френды нужны для юнит тестов и свободных операторов. Если это не твой случай, то значит архитектура спроектированна неправильно. Её нужно переделывать.

класс UI который отвечает за интерфейс, его логику

Это тоже нужно разделить на две части.

ox55ff ★★★★★
()

Вроде выглядит как классическое (ну почти классическое вьюхи 2) MVVM. UI (Model по факту, где логика), View (у тебя их 2 на разных движках AaaRenderer и BbbRenderer) и ViewModel которая прослойка между Model и View (у тебя это рендер). Посмотри как люди делают на других языках такое, особенно часто это на WPF/Avalonia и шарпе. На плюсах почти то же самое, только с поправкой на то что это плюсы.

zx_gamer вон дело пишет, если всё правильно делать, то можно спокойно хоть 100 рендеров приделать.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 3)
Ответ на: комментарий от peregrine

Фак, какая же теперь всратая разметка…

Для того чтобы рисовать UI, надо иметь доступ к его кишкам.

Не надо. Renderer должен предоставлять API достаточное для рисования чего угодно.

Нет, ну ты чо, с целью дьявольского смеха же. У Руки Ыгееук Херба Саттера аж четыре способа, специально подобрано чтоб: френд, дефайн, р-каст, определение шаблонного метода.

//дьявольский смех тут
anonymous
()

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

vtVitus ★★★★★
()
Последнее исправление: vtVitus (всего исправлений: 1)