Eu estou tentando entender amigo C ++. Quando é o bom caso de uso para usar amigo? Suponho que, se queremos permitir que outra classe tenha acesso aos atributos de outra classe, por que não a tornamos pública ou herdamos dessa classe?
Obrigado pela ajuda.
Respostas:
Tornar um membro da classe
public
significa conceder acesso a todos , quebrando completamente o encapsulamento.Herdar de uma classe geralmente não é desejável, se a classe de amigo não for uma subclasse. Subclassificar apenas para ter acesso aos componentes internos de uma classe é um grave erro de design. E mesmo uma subclasse não pode ver os membros privados de sua classe base.
Um uso típico de
friend
é para operadores que não podem ser membros, como operadores de fluxo,operator+
etc. Nesses casos, a classe real à qual estão associados não é (sempre) o primeiro parâmetro da função; portanto, a função não pode ser implementado como um método membro.Outro exemplo é a implementação de um iterador para uma coleção. O iterador (e somente o iterador) precisa ver os elementos internos de sua coleção pai, no entanto, não é uma subclasse da coleção.
fonte
O exemplo para o qual eu mais frequentemente vi classes de amigos usadas em C ++ está no teste de unidade. Os testes de unidade geralmente querem saber tudo sobre seus internos, mas não fazem parte de você, e não faz sentido que eles tentem herdar de você.
Se você não está familiarizado com a escrita de testes de unidade, sugiro que você comece imediatamente.
fonte
Esta pergunta deve estar no stackoverflow. De qualquer forma, você usa um amigo apenas quando deseja compartilhar as partes privadas da sua classe com outra (s) aula (s), mas não com mais ninguém. Se você os tornar públicos, todos poderão ver suas partes íntimas (trocadilhos ;-P). Existem duas restrições importantes que reforçam a privacidade: 1) você precisa especificar quem é seu amigo. Ninguém mais pode ser um amigo. 2) você não pode herdar comportamento "amigável" nas subclasses da classe de amigos
fonte
Um uso típico é conceder acesso a funções que fazem parte da interface da classe, mas graças a outras regras não podemos realmente fazer parte da classe. Inserters / extratores para iostreams são um exemplo clássico:
Tornar esses operadores membros da classe não funcionará. Uma operação de E / S se parece com:
Para um operador implementado como uma função membro, isso seria resolvido como:
Ou seja, a função teria que ser membro de
std::cout
, não desomething
. Como não queremos modificarstd::ostream
constantemente, nossa única opção razoável é sobrecarregar o operador com uma função livre em vez de uma função membro. Isso nos deixa com duas possibilidades: ignorar completamente o encapsulamento e tornar público tudo na classe, ou mantê-lo privado, mas conceder acesso às poucas coisas que realmente precisam dele.Tornar outra classe amiga é um pouco menos comum. Nesse caso, você normalmente cria algo da ordem de um módulo ou subsistema - um conjunto de classes que trabalham juntos e têm algum grau de acesso especial um ao outro que não é concedido ao mundo em geral.
fonte
Há um bom exemplo da necessidade de classes de amigos nesta solicitação de classes semelhantes a amigos em C # , um idioma que não as possui.
Atacado citado aqui:
Mads Torgersen, PM do idioma C #, chegou a responder a essa proposta, afirmando que a preocupação é realmente válida, mas não tem certeza da implementação específica sugerida lá.
O C ++
friend
é apenas uma das maneiras de resolver o problema descrito.fonte
Quando você deseja que suas aulas tenham relacionamentos monogâmicos.
Por exemplo, quando você não deseja que classes desconhecidas acessem suas partes privadas, mas seus parceiros precisam de acesso.
fonte
Eu achei as classes de amigo em C ++ úteis quando em Java eu teria usado o acesso ao pacote. Ou seja, eu tenho um monte de classes que estão tão intimamente relacionadas que são escritas e mantidas como uma unidade, no (s) mesmo (s) arquivo (s) de origem. Quem trabalha em um deles está realmente trabalhando em todos eles. Os invariantes que eles mantêm, mantêm juntos. Faz sentido para eles ver os internos um do outro para que eles possam manter sua invariável compartilhada.
O que não faz sentido é o acesso protegido. Se não é seguro expor parte de meus internos ao público, não é seguro expô-lo a quaisquer jackanapes que surgem mais tarde em um projeto completamente não relacionado e afirme ser minha subclasse. Deixe as subclasses usarem minha interface pública, assim como todos os outros. (A menos que sejam amigos, mas nesse caso eu os escrevi e os implementei na mesma fonte, portanto, dificilmente são de outro projeto.)
fonte
Vamos dizer que existe uma função externa que requer que você execute operações em membros privados ou protegidos de duas classes diferentes dentro do seu programa. agora, para que essa função tenha acesso e utilize esses membros da classe, você deve torná-la amiga das duas classes. Tendo em mente que, ao torná-lo amigo de ambas as classes, ele não é um membro das classes, apenas ganha a prevalência de se referir aos membros privados ou protegidos dessas classes. Posso dizer que você precisaria usar uma função de amigo quando quiser operar em objetos de duas classes diferentes. Embora o uso excessivo da função e classe do amigo possa reduzir o valor do encapsulamento.
fonte