2016-04-22 5 views
2

здесь им не понять концепцию очень хорошо, или я прав .... Так давайте этот «друг» классовую пример здесь:Friend класса В C++

class MyClass{ 
friend class AnotherClass; 
private: 
     int secret; 
} 

class AnotherClass{ 
public: 
     void getSecret(MyClass mc){ 
      return mc.secret; 
     } 
} 

Так что да ... в приведенном выше коде он будет работать, если вы это сделаете ... но в целом, почему вы не можете использовать геттеры и сеттеры все время вместо класса друга? Является ли причина использования класса друзей из-за «утомительности»?

ответ

6

friend предназначен для тех случаев, когда вы не хотите раскрывать геттеры/сеттеры/внутренние устройства всем, но только для одного класса. Так что это инструмент для инкапсуляции.

Например, если вы предоставили общественности getSecret в MyClass, каждый может иметь доступ к этой частной переменной, даже если они не должны знать об этом. Это нарушает инкапсуляцию. friend есть, чтобы исправить эту проблему, так что только те классы, которые должны знать о secret, имеют к ней доступ.

Как сказал @nicomp, «это как предоставление вашему физическому другу ключа к вашему дому, но вы не знаете, что с ним делать». Таким образом, класс friend имеет неограниченный доступ ко всем внутренним группам, с которыми он дружит. Это несчастливо, но ключ (здесь не каламбур) заключается в том, чтобы сохранить как можно меньше классов, чтобы это не стало проблемой, что также было бы в соответствии с принципом единой ответственности.

+0

К сожалению, я слишком ленив, чтобы отредактировать его в своем ответе, но если кто-то заботится, это ['Drawable' class] SFML (http://www.sfml-dev.org/documentation/2.0/classsf_1_1Drawable .php), который использует «друг» довольно умно. – emlai

0

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

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

2

Публикация геттер или 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 - это инструмент, который позволяет вам выборочно предоставлять доступ, но вы всегда должны тщательно рассмотреть вопрос о том, должен ли этот доступ быть предоставлен, или же нужна ли ему функция/класс, которая была бы лучше в качестве члена вашего класса.

+0

То, что сказал @tuple_cat ... – amanuel2

+0

@AmanuelBogale да, суть та же. Я бы хотел подумать, что я предоставил дополнительный контекст? – Andrew

+0

@AmanuelBogale Это полностью зависит от вас. [Рекомендации здесь] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) могут помочь ... – Andrew

Смежные вопросы