|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
||
Использование инструмента friend в проекте24.06.2015, 18:52. Показов 5912. Ответов 21
Метки нет (Все метки)
Добрый день,
я считаю, что дать полный доступ классу на все внутренности - это нарушение инкапсуляции, пораждении дыри через которую можно не то, что ранить - а убить. Человек правит свой класс B которому дали полный на класс А. Всё работает - всё супер. Компилирует всё работает. Но в каких-то случаях оно падает. К примеру (синтаксический пример) в классе А переменная x не может быть 13. А владелец класса В напрямую пишит: classA->x = 13; Более того закрепить очередную внешнюю связь дял класса это разве SOLID одобрено?)
0
|
||
| 24.06.2015, 18:52 | |
|
Ответы с готовыми решениями:
21
Использование инструмента Авторазмер в Компас 3D 17 Использование инструмента Элемент выдавливания в Компас 3D 17 Перегрузка операторов, friend или нет friend? |
|
76 / 76 / 32
Регистрация: 14.04.2014
Сообщений: 408
|
||||||
| 24.06.2015, 19:14 | ||||||
|
а что мешает обернуть все в методы, где проверять
0
|
||||||
|
15 / 15 / 3
Регистрация: 04.02.2013
Сообщений: 124
|
|
| 24.06.2015, 19:18 | |
|
А как тогда реализовывать отношения "один ко многим"? Тот же пример из Праты, класс телевизора и класс пульта дистанционного управления, ведь один пульт может управлять несколькими ящиками. Тут без друзей либо нужно открывать закрытые члены, что опять же убивает инкапсуляцию, либо писать какие-то хитрые громоздкие классы для такого рода отношений, менее понятные и менее абстрактные. А если в телевизоре только 12 каналов, а на пульте управления 13 кнопок с каналами, то ничего страшного, пусть телевизор сам решает, что ему делать в случае сигнала 13 канала с пульта. Можно и исключения, наверное, использовать. ИМХО
Добавлено через 1 минуту Кстати, как такие отношения реализованы в других языках ООП? Добавлено через 2 минуты Кстати, друзья даже менее убивают инкапсуляцию, чем просто вскрытие закрытого поля. Если поле будет в открытом разделе, то канал и кофеварка сможет переключить.
0
|
|
|
76 / 76 / 32
Регистрация: 14.04.2014
Сообщений: 408
|
|
| 24.06.2015, 19:22 | |
|
я прочел ту тему, и понял о чем речь.
Думаю, что этот оператор включен в язык для расширения функционала, и не является мастхэв. Возможно он сделан для того, чтобы можно было одни и теже данные делить на несколько классов, которые в 1 обьеденить никак нельзя. Тогда и получается структура вида 1класс с набором данных и несколько френдов оперирующих этими данными, но в таком случае проверки на корректность чтения/записи остаются за самими классами. ПОлучается сильная связанность к тому же.
0
|
|
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|
| 24.06.2015, 19:35 [ТС] | |
|
То, что я вижу - 95% людей используют friend потому, что ТАК ЛЕГЧЕ.
0
|
|
|
15 / 15 / 3
Регистрация: 04.02.2013
Сообщений: 124
|
|
| 24.06.2015, 19:42 | |
|
0
|
|
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|
| 24.06.2015, 19:50 [ТС] | |
|
ну написать 100500 геттеров и толковый интерфейс для работы с классом дольше, чем одной строкой дать "алл инклюдед в отелях Турции"
0
|
|
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
|||||||||||||||||
| 24.06.2015, 21:11 | |||||||||||||||||
Сообщение было отмечено rikimaru2013 как решение
Решение
Раз уж меня сюда процитировали, то мне, видимо, необходимо ответить.
Как я уже говорил, friend - это очень мощный механизм. И из-за этого его очень просто использовать неправильно. Обычный довод, который используют т.н. "противники" - это нарушение инкапсуляции. Я приведу несколько примеров, когда friend не только не нарушает инкапсулцию, но и усиливает ее. Пример 1: Вариант на тему "Порождающие классы". Предположим, что у нас есть классы, объекты которых не разрешено создавать кому попало. Заведем себе класс, который, будет порождать наши объекты. Как же запретить остальным это делать "by design"? Один из способов - это поместить конструкторы наших классов в private, а создающую функцию класса-строителя определить другом:
Пример 2: Интераторы. У нас есть класс, которому нужен итератор. Внутренней структуры мы предоставлять не хотим., но итератору необходимо работать с некоторыми внутренними данными.
Пример 3: Функция относится к интерфейсу класса, но требует левым операндом другой объект. Никогда не задумывались, почему операторы !=, ==, и << >> очень часто реализуют как дружественные функции? Наш класс имеет некоторые данные, которые должны быть сравнены, независимо от того, слева или справа от оператора != или == он находится. Иногда так бывает, что класс дает геттеры для всех данных, которые можно так сравнить, а что, если нет? Заводить открытый геттер для внутренних данных, только ради того, чтобы использовать его в функции сравнения и не делать ее friend? Вот где настоящее нарушение инкапсуляции. В интерфейсе класса появился открытый метод к внутренним данным, которые не должны быть видны, но теперь их может использовать кто угодно! В этом вопросе сошлюсь также на правило 19 замечательной книжки Скотта Мейерса "Эффективное использование С++". Очень важно здесь учитывать, что этот пример не призывает использовать friend везде, где требуется перегрузка операторов, а лишь там, где это действительно необходимо. Пример 4, риторический: "А чего он, собственно, нарушает?" Итак, класс сам определяет какую функцию или класс сделать другом. Ответственность на этом полностью лежит на разработчике класса. Функцию, объявленная другом, точно так же становится частью интерфейса, как и любой метод. С этой точки зрения ничего не меняется
Пример 5, не мой: Этот пример можно посмотреть в книге "Новые сложные задачи на С++" Герба Саттера (задача 8). ______ Все вышенаписанное не стоит воспринимать как призыв использовать friend везде (чем иногда грешат советы по перегрузке операторов здесь, на форуме). Можно гораздо больше текста написать о вреде, который может быть нанесен необдуманным использованием friend. Но это уже сделали вместо меня, гораздо более авторитетные люди. Посему, предлагаю всем сомневающимся открыть правило 44 книги "Стандарты программирования на С++", там можно найти популярные причины отказа от friend, а также алгоритм выбора варианта определения функции как части интерфейса (свободная функция, функция-член и свободная функция-друг). ______ Завершить хотелось бы цитатой, которая должна быть эпиграфом к этому посту:
http://stackoverflow.com/quest... as-friends http://stackoverflow.com/quest... r-function http://stackoverflow.com/quest... -the-prope
16
|
|||||||||||||||||
|
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
|
||
| 24.06.2015, 21:20 | ||
|
Вам надо Страуструпа почитать, он в своей книжке доходчиво объясняет для чего нужны классы-друзья, подчеркивая, что их нужно применять только для отражения тесно связанных концепций. Ну, тот же пример оператора умножения матрицы на вектор, который должен иметь доступ к обоим этим классам. Еще одна причина – неявные преобразования типов. Бинарные операторы с таким преобразованием должны быть или глобальными функциями, или дружественными, например, будь бинарные операторы комплексных чисел членами класса complex, мы не смогли бы к целому числу прибавить комплексное или к комплексному действительное.
2
|
||
|
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
||
| 24.06.2015, 21:35 | ||
|
0
|
||
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
||||||||||||
| 07.08.2015, 00:03 [ТС] | ||||||||||||
Как оптимизировать этот момент под ваш пример "friend factory"
0
|
||||||||||||
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
|||||||||||||||||||||
| 07.08.2015, 00:53 | |||||||||||||||||||||
|
rikimaru2013, запросто, можно заменить тип на enum id.
Кликните здесь для просмотра всего текста
Решение конечно не из разряда очевидных, но поддерживать его относительно легко. Добавление новых типов осуществляется только в одном файле. Можно и другой, более динамический способ придумать: Кликните здесь для просмотра всего текста
Опять же, это не все варианты. Но я уже устал сегодня. Добавлено через 9 минут rikimaru2013, небольшая поправка для второго примера, а то сейчас прилетит кто-нибудь с дикими воплями, что я нарушаю инкапсуляцию. В определении класса builder в h нужно оставить только объявление класса make, чтобы его невозможно было использовать откуда-то еще кроме, кроме builder.cpp
2
|
|||||||||||||||||||||
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
||
| 07.08.2015, 13:57 [ТС] | ||
|
Можете скзаать ваше мнение по этому поводу - чтобы вы использовали?
0
|
||
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
|||
| 07.08.2015, 15:18 | |||
|
1
|
|||
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
||
| 07.08.2015, 15:39 [ТС] | ||
|
0
|
||
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
||
| 07.08.2015, 15:44 | ||
![]() Вообще конечно отсутствие перекомпиляции приводит к нарушению ODR, но в данном случае оно достаточно невинно. Добавлено через 2 минуты rikimaru2013, еще можно избавиться от единого enum, а вместо этого определять уникальную константу прямо в новом юните. Становится сложнее контролировать уникальность, но вот перекомпиляции уже не будет точно, т.к. каждая константа в своем отдельном файле.
0
|
||
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|||||||
| 07.08.2015, 15:51 [ТС] | |||||||
0
|
|||||||
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
||
| 07.08.2015, 15:57 | ||
|
Вообще тут нет правильных и неправильных вариантов. Ты сейчас похоже хочешь найти серебряную пулю, а ее нет. Взвешивай достоинства и недостатки различных примеров применительно к своему проекту. Это путь к истине. Я могу только вариант предложить, а подходит тебе он или нет - решай сам.
1
|
||
|
"C with Classes"
|
|
| 22.11.2022, 20:34 | |
|
0
|
|
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
|
| 22.11.2022, 20:35 | |
|
1
|
|
| 22.11.2022, 20:35 | |
|
Помогаю со студенческими работами здесь
20
Использование в проекте аккумулятора. Использование интерполяции в проекте Использование MongoDB в С++ проекте Использование фреймворков в проекте Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта
Симптом:
После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
|
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
|
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут.
В век Веб все очень привыкли к дизайну Single-Page-Application .
Быстренько разберем подход "на фреймах".
Мы делаем одну. . .
|