Публикация геттер или setter разрешает кому-либо доступ. Они имеют некоторые виды использования, в частности, для поддержания инвариантов класса, когда какое-то свойство изменяется, но геттер/сеттер пара, которые выглядят как следующий код не не лучше, чем открытые,:
class A {
public:
int getX() const { return x; };
void setX(int x_) { x = x_; };
private:
int x;
};
getX()
и setX()
функция ничего не делать, кроме предоставления доступа к x
. Каждый может их использовать, поэтому любой может изменить значение x
. Тогда нет смысла делать это частным.
Если, вместо этого, только некоторые классы или функции должны быть в состоянии изменить x
, вы можете сделать их друзьями класса A
. Это ограничивает доступ только к тем друзьям, а не дает их всем.
Таким образом, friend
является инструментом инкапсуляции, позволяя инкапсуляции быть шире, чем «только мой собственный класс» (частные члены) или «только мой класс и классы, которые вытекают из него» (защищенные члены). Другу не нужно находиться в одной иерархии классов (это вообще не должен быть класс, функции могут быть друзьями), но он все же позволяет вам ограничивать доступ только к тем вещам, которые на самом деле нуждаются в нем.
Обратите внимание, что, подобно геттерам и сеттерам, его следует использовать экономно. Инкапсуляция - это хорошо, и, по возможности, частные члены вашего класса должны оставаться такими - частными. friend
- это инструмент, который позволяет вам выборочно предоставлять доступ, но вы всегда должны тщательно рассмотреть вопрос о том, должен ли этот доступ быть предоставлен, или же нужна ли ему функция/класс, которая была бы лучше в качестве члена вашего класса.
К сожалению, я слишком ленив, чтобы отредактировать его в своем ответе, но если кто-то заботится, это ['Drawable' class] SFML (http://www.sfml-dev.org/documentation/2.0/classsf_1_1Drawable .php), который использует «друг» довольно умно. – emlai