C ++ para amigo ou não amigo

14

Eu tenho uma programação orientada a objetos com curso de c ++ neste semestre na faculdade e estávamos aprendendo sobre funções de amigos.

Eu instintivamente não gosto deles por sua capacidade de contornar a segurança que o encapsulamento e a ocultação de dados fornecem, li alguns artigos na internet e algumas pessoas acharam que era uma boa ideia com alguns usos legítimos.

O que um especialista em OOPs diria sobre funções de amigos em C ++? Devo apenas passar por cima ou devo aprender mais sobre isso?

    
por nikhil 04.09.2011 / 09:57
fonte

8 respostas

11

Nem sempre é conveniente fazer todas as funções relacionadas a membros da classe C ++ dessa classe. Por exemplo, imagine uma implementação de álgebra vetorial com multiplicação escalar. Queremos escrever:

 double a;
 Vector v, w;
 w = v * a;

Podemos fazer isso com uma função de membro:

public class Vector {
 ...
 Vector operator*(double a);
}

Mas também gostaríamos de escrever:

w = a * v

Isso requer uma função livre:

 Vector operator*(double a, Vector v)

A palavra-chave friend foi adicionada ao C ++ para suportar esse uso. A função free faz parte da implementação da classe Vector, e deve ser declarada no mesmo cabeçalho e implementada no mesmo arquivo de origem.

Da mesma forma, podemos usar friend para simplificar a implementação de classes strongmente acopladas, como uma coleção e um iterador. Novamente, eu declararia ambas as classes no mesmo cabeçalho e as implementaria no mesmo arquivo de origem.

    
por 04.09.2011 / 20:29
fonte
15

As funções de amigos não são diferentes das funções de membro em termos de encapsulamento. Eles podem, no entanto, oferecer outras vantagens, como ser mais genérico, especialmente no que se refere aos modelos. Além disso, alguns operadores só podem ser especificados como funções livres, portanto, se você deseja que eles tenham acesso de membro, você deve friend .

É melhor usar friend de uma única função do que ser forçado a fazer algo que você não quer que seja público. Isso significa que o mundo inteiro pode usá-lo, em vez de apenas uma função.

    
por 04.09.2011 / 12:26
fonte
5

Se você é apaixonado pelo que faz, estaria aprendendo tudo sobre o C ++. Aprenda o que eles estão acostumados, como usá-los, e então - e só então - decida não usá-los. No mínimo, você estará preparado ao ler o código de outra pessoa que usa essa faceta do C ++.

    
por 04.09.2011 / 10:12
fonte
5

" O que um especialista em OOPs diria ... " Isso depende principalmente de como ele é especialista em C ++, que - por sua própria especificação - não é (e não quer ser) uma linguagem para purista.

OOP Zealots não usam C ++ (eles preferem o Smalltalk e como o Java).

Zelots de programação funcional não usam C ++ (eles preferem o LISP e seus sucessores)

A maioria dos especialistas em OOP não gostam da função friend simplesmente porque querem que a parte OOP do C ++ se comporte como Smalltalk. Mas o C ++ não é Smalltalk, e eles não podem nem entender que amigo não quebra o encapsulamento , pela simples razão de que uma função não pode ser amiga da sua classe sem que sua classe a queira .

E do ponto de vista "funcionalidade", entre a.fn(b) e fn(a,b) não há diferença (onde fn é amigo): as partes envolvidas são as mesmas. Simplesmente, uma sintaxe pode ser mais adequada que outra: se fn é comutativa em relação a a e b , fn(a,b) é provavelmente mais adequado que a.fn(b) (onde parece ter um "papel especial" que, de fato, isso não acontece.)

    
por 04.09.2011 / 18:54
fonte
5

Does "friend" violate encapsulation?

No. It does not. "Friend" is an explicit mechanism for granting access, just like membership. You cannot (in a standard conforming program) grant yourself access to a class without modifying its source.

    
por 05.09.2011 / 07:34
fonte
2

A FAQ do C ++ é sucinta:

Use a member when you can, and a friend when you have to.

O FAQ apresenta uma das formas mais úteis de pensar sobre amizade:

Many people think of a friend function as something outside the class. Instead, try thinking of a friend function as part of the class's public interface. A friend function in the class declaration doesn't violate encapsulation any more than a public member function violates encapsulation: both have exactly the same authority with respect to accessing the class's non-public parts.

Talvez o uso mais comum de funções de amigos seja a sobrecarga < < para I / O.

    
por 07.09.2011 / 22:53
fonte
0

As funções de amigos são melhor usadas para definições de operador definidas pelo usuário. Eles são úteis em outras situações, mas se você estiver especificando classes de amigos com frequência, então você pode estar em um desvio de design (apenas uma boa auto-verificação para usar enquanto escreve o código).

Tenha cuidado com a instrução "security" na pergunta original. Os modificadores de acesso estão lá para evitar que você grave códigos ruins em acidentes, da mesma forma que o compilador. Os modificadores de acesso limitam a interface e servem para comunicar quais funções são importantes para usar a classe (pública e protegida) e quais foram criadas como parte de tornar a classe mais bonita para os mantenedores (privados). Os modificadores não constituem segurança, pois há muitas maneiras de obter dados privados. Por exemplo, obtenha um ponteiro para a classe e seu tamanho e vá pescar.

    
por 05.09.2011 / 22:04
fonte
-2

As funções de amigo do C ++ estão intimamente relacionadas à seguinte funcionalidade:

  1. funções gratuitas
  2. funções estáticas
  3. funções de amigos

Isso significa que eles não têm esse ponteiro e, portanto, estão fora da classe / objeto. Por outro lado, eles geralmente pegam parâmetros que os fazem pertencer novamente à classe. Veja um exemplo que esclarece o link:

class B;
class A {
public:
    friend void f(A &a, B &b);
private:
    int m_a;
};
class B {
public:
   friend void f(A &a, B &b);
private:
   int m_b;
};
void f(A &a, B &b) { /* uses both A's and B's private data */ }

A única diferença entre funções estáticas e funções de amigos é que uma função de amigo pode usar várias classes.

Usar mecanismo de amigo em c ++ requer programadores que tenham cerca de 10 a 15 anos de experiência com o modo de programação em c ++ e, assim, inicialmente, você deve evitá-lo. É um recurso avançado.

    
por 04.09.2011 / 11:30
fonte