Распространённое заблуждение, что friend функции нарушают инкапсуляцию. Это неправда. Когда friend используются правильно, они наоборот улучшают инкапсуляцию, предоставляя контролируемый доступ к приватным членам без их публичного раскрытия.
Friend функции обычно предпочтительнее для операций печати одного класса, потому что они держат детали реализации в приватной части и сохраняют чистый публичный интерфейс.
Методы printOn() полезны в основном когда:
protected или private (не public)Использование публичного метода printOn() чтобы избежать friend функций создаёт ненужные проблемы:
Никакой экономии на поддержке: Оба подхода требуют N строк кода с доступом к приватным/защищённым членам. Перемещение кода из friend функции в метод члена не снижает затраты на поддержку — это может даже их увеличить из-за дополнительных накладных расходов на вызов функции.
Запутывает пользователей: Раскрытие публичного метода, который программисты «не должны использовать», создаёт путаницу. Это нарушает принцип наименьшего удивления и делает класс сложнее использовать правильно.
Ненужное раздувание API: Пользователи видят несколько способов достичь одного результата, и приходится документировать, какой метод на самом деле нужно использовать.
class Fred {
private:
friend std::ostream& operator<< (std::ostream&, const Fred&);
// детали реализации
};
std::ostream& operator<< (std::ostream& o, const Fred& fred) {
// прямой доступ к приватным членам
return o;
}
Используй friend функции для простых задач печати. Оставляй защищённые/приватные методы printOn() для иерархий классов. Избегай публичных методов printOn() полностью — они добавляют сложность без какой-либо пользы с точки зрения поддержки.
Friend функции по своей природе нарушают принципы инкапсуляции, потому что позволяют внешнему коду получать доступ к приватным членам.
Новый — ещё не проверен сообществом
Вы