C ++ a un amigo o no a un amigo

14

Este semestre en la universidad tengo una programación orientada a objetos con c ++ y estábamos aprendiendo sobre las funciones de los amigos.

Instintivamente me disgustan por su capacidad para eludir la seguridad que brinda la Encapsulación y la Ocultación de Datos, leí algunos artículos en Internet y algunas personas pensaron que era una buena idea con algunos usos legítimos.

¿Qué diría un experto en OOP sobre las funciones de los amigos en C ++? ¿Debo hojearlo o aprender más sobre él?

    
pregunta nikhil 04.09.2011 - 09:57

8 respuestas

11

No siempre es conveniente hacer que todas las funciones relacionadas con una clase C ++ sean miembros de esa clase. Por ejemplo, imagine una implementación de álgebra vectorial con multiplicación escalar. Queremos escribir:

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

Podemos hacer esto con una función miembro:

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

Pero también nos gustaría escribir:

w = a * v

Esto requiere una función libre:

 Vector operator*(double a, Vector v)

La palabra clave friend se agregó a C ++ para admitir este uso. La función gratuita es parte de la implementación de la clase Vector, y debe declararse en el mismo encabezado e implementarse en el mismo archivo fuente.

De forma similar, podemos usar friend para simplificar la implementación de clases estrechamente acopladas, como una colección y un iterador. Una vez más, declararía ambas clases en el mismo encabezado y las implementaría en el mismo archivo fuente.

    
respondido por el kevin cline 04.09.2011 - 20:29
15

Las funciones de amigo no son diferentes de las funciones miembro en términos de encapsulación. Sin embargo, pueden ofrecer otras ventajas, como ser más genéricos, especialmente cuando se trata de plantillas. Además, algunos operadores solo pueden especificarse como funciones gratuitas, por lo que si desea que tengan acceso de miembros, debe friend .

Es mejor friend una única función que forzarte a hacer algo que no quieres que sea público. Eso significa que todo el mundo puede usarlo, en lugar de una sola función.

    
respondido por el DeadMG 04.09.2011 - 12:26
5

Si te apasiona lo que haces, estarías aprendiendo todo sobre C ++. Conozca para qué se usan, cómo usarlos y luego, y solo entonces, decida no usarlos. Como mínimo, estará preparado cuando lea el código de otra persona que usa esta faceta de C ++.

    
respondido por el Jonathan Khoo 04.09.2011 - 10:12
5

" ¿Qué diría un experto en OOP ... ? En su mayoría depende de qué tan experto sea en C ++, que, por su propia especificación, no es (y no quiere serlo) Un lenguaje para puristas.

OOP Los fanáticos no usan C ++ (prefieren Smalltalk, y les gusta Java).

Zelots de programación funcional no usan C ++ (prefieren LISP y sus sucesores)

A la mayoría de los expertos en OOP no les gusta la función de amigo simplemente porque quieren que la parte OOP de C ++ se comporte como Smalltalk. Pero C ++ no es Smalltalk, y ni siquiera pueden entender que amigo no rompe la encapsulación , por la sencilla razón de que una función no puede ser amiga de su clase sin que su clase lo quiera .

Y desde el punto de vista de la "funcionalidad", entre a.fn(b) y fn(a,b) no hay diferencia (donde fn es un amigo): las partes involucradas son las mismas. Simplemente, una sintaxis puede ser más adecuada que otra: si fn es conmutativa con respecto a a y b , fn(a,b) es probablemente más adecuada que a.fn(b) (donde parece que tiene un "rol especial" que, de hecho, no lo hace.)

    
respondido por el Emilio Garavaglia 04.09.2011 - 18:54
5
  

¿"Amigo" viola la encapsulación?

     

No. No es asi. "Amigo" es un mecanismo explícito para otorgar acceso, al igual que la membresía. No puede (en un programa de conformidad estándar) otorgarse acceso a una clase sin modificar su origen.

    
respondido por el fredoverflow 05.09.2011 - 07:34
2

La Preguntas frecuentes de C ++ es concisa:

  

Use un miembro cuando pueda y un amigo cuando tenga que hacerlo.

Las preguntas frecuentes presentan una de las formas más útiles de pensar acerca de la amistad:

  

Muchas personas piensan que un amigo funciona como algo fuera de la clase.   En su lugar, intente pensar en la función de un amigo como parte de la clase.   interfaz pública Una función amiga en la declaración de clase no   violar la encapsulación más de lo que una función de miembro público viola   encapsulamiento: ambos tienen exactamente la misma autoridad con respecto a   acceder a las partes no públicas de la clase.

Quizás el uso más común de las funciones de amigo es la sobrecarga < < para E / S.

    
respondido por el Gnawme 07.09.2011 - 22:53
0

Las funciones de amigo se utilizan mejor para las definiciones de operador definidas por el usuario. Son útiles en otras situaciones, pero si te encuentras especificando con frecuencia las clases de amigos, es posible que te encuentres en un desvío de diseño (solo una buena auto-verificación para usar mientras escribes el código).

Tenga cuidado con la declaración de "seguridad" en la pregunta original. Los modificadores de acceso están ahí para evitar que escribas código incorrecto en caso de accidente, al igual que el compilador en cierto modo. Los modificadores de acceso limitan la interfaz y sirven para comunicar qué funciones son importantes para usar la clase (pública y protegida), y cuáles se crearon para hacer que la clase sea más bonita para los mantenedores (privada). Los modificadores no constituyen seguridad, ya que hay muchas formas de obtener datos privados. Por ejemplo, obtenga un puntero a la clase y su tamaño, y vaya a pescar.

    
respondido por el anon 05.09.2011 - 22:04
-2

Las funciones de amigo de C ++ están estrechamente relacionadas con la siguiente funcionalidad:

  1. funciones libres
  2. funciones estáticas
  3. funciones de amistad

Esto significa que no tienen este puntero y, por lo tanto, están fuera de la clase / objeto. Por otro lado, a menudo toman parámetros que los hacen pertenecer nuevamente a la clase. Aquí hay un ejemplo que aclara el enlace:

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 */ }

La única diferencia entre las funciones estáticas y las funciones de amigo es que una función de amigo puede usar varias clases.

El uso del mecanismo de amistad en c ++ requiere que los programadores tengan entre 10 y 15 años de experiencia con la forma de programación de c ++ y, por lo tanto, inicialmente debe evitarlo. Es una característica avanzada.

    
respondido por el tp1 04.09.2011 - 11:30

Lea otras preguntas en las etiquetas