Использование классов «друга» в разработке игр

9

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

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

Создание общедоступных методов получения / установки этих личных данных обнажает вещи, которые на самом деле не должны изменяться невольно.

Был бы компромисс здесь, чтобы использовать классы друга? или есть какой-то недостаток в классах друзей, которых я не вижу.

Дэвид Янг
источник

Ответы:

8

Есть два основных недостатка классов фридинга.

  1. Вы не можете выбирать, что вы хотите показать своим друзьям. Это все или ничего. Это может оказаться проблематичным, если вы пытаетесь навязать обязательное использование какого-либо несущественного метода установки.
  2. Ваши два класса теперь несколько связаны в том смысле, что друг знает о друге.

При этом использование классов-друзей определенно может улучшить инкапсуляцию, особенно если альтернативой являются публичные методы получения / установки.

Также, связанный вопрос по SO: /programming/521754/when-to-use-friend-class-in-c

тетрада
источник
5

Инкапсуляция хороша, но разделение проблем приятнее.

Класс, обращающийся к «некоторой частной части» другого класса, может указывать на то, что код изначально плохо спроектирован.

Каждый раз, когда вы оказываетесь в месте «черт возьми, мне нужно устроить урок здесь», вопрос, который вы должны задать себе: «Я делаю это правильно, или есть более чистый способ?» (ака «Это будет кусать меня в задницу позже?»).

Если вы уверены в «дружелюбии», положите его туда без колебаний.

egarcia
источник
Я понимаю, как использование класса друга тесно связывает один класс с другим. Мне было интересно, есть ли в частности шаблон проектирования, который облегчает проблему, потому что просто завернуть что-то в метод получения / установки может быть худшим решением.
Дэвид Янг
1
Интересный пример: шаблон Factory в C ++ требует «друга» из-за использования приватных конструкторов.
Дэвид Янг
2

Другой вариант - использовать идиому PIMPL , где частью реализации структуры является указатель на другой тип. Большинство пользователей класса просто включают обычный заголовочный файл, где реализация представляет собой непрозрачный указатель. Классы, которым требуется доступ к частным данным, могут включать заголовок, определяющий другой тип, и использовать интерфейс, который он предоставляет.

Это общий шаблон для программистов на Си, которым нужна функциональность, похожая на друга. По моему мнению, он также более тесно связан с размышлением о разделении интересов (обычно хороший принцип проектирования, который приводит к многоразовому, ортогональному коду), а не об инкапсуляции (специфичная для ОО методика, которая полезна для реализации разделения интересов, но также часто используется неправильно). усложнять вещи).

Он имеет преимущество перед другом в том, что он вообще не связывает друга с другом. Некоторые люди могут утверждать, что это недостаток, поскольку теперь любой может «подружиться» с вашим классом. Я думаю, что это необоснованный страх, так как вы все еще делаете отношения явными (включая заголовок). Если вы боитесь этого, вы боитесь вашей (или вашей коллеги) способности принимать умные архитектурные решения. Но если вы не можете принять эти решения должным образом позже, почему вы доверяете себе friendсейчас?

Это имеет недостаток затрат времени выполнения. Хранение данных в указателе приводит к ухудшению когерентности кэша и увеличению количества выделений, а также для его очистки необходим деструктор.


источник
+1 интересно, не слышал об этой концепции, происходящей из фона Java.
Дэвид Янг