2009-02-21 5 views

Respuesta

3

Utilizaría una función de amigo por el mismo tipo de razones que utilizaría una clase de amigo, pero en función de un miembro (en lugar de una clase completa). Algunas buenas explicaciones están en this thread.

Si bien las funciones y clases de amigo no infringen la encapsulación, pueden ser útiles en algunos escenarios. Por ejemplo, es posible que desee permitir que un arnés de prueba acceda a las partes internas de la clase para permitirle realizar pruebas de la caja blanca. En lugar de abrir toda la clase al arnés de prueba, podría abrir una función particular que acceda a las partes internas requeridas por el arnés de prueba. Si bien esto aún infringe la encapsulación, es menos riesgoso que abrir toda la clase.

Consulte también this article para obtener más información acerca de las clases y funciones de amigos.

0

A veces el nivel de protección público/privado/protegido no es suficiente para las situaciones del mundo real. Entonces, damos una pequeña cláusula de salida que ayuda sin tener que hacer que los métodos sean públicamente accesibles.

Yo personalmente uso esto de la misma manera que Java usa el nivel de protección 'Paquete'.
Si tengo una clase en el mismo paquete que necesita acceso consideraré usar friend. Si se trata de una clase en otro paquete, entonces me pregunto por qué esta clase necesita acceso y mira mi diseño.

1

Ver C++ FAQ Lite:

A veces los amigos son sintácticamente mejor (por ejemplo, en la clase de Fred, funciones friend permiten el parámetro Fred a ser segundo, mientras que los miembros lo requieran ser el primero). Otro buen uso de las funciones de amigo son los operadores aritméticos de infijo binario. Por ejemplo, aComplex + aComplex debe definirse como un amigo en lugar de un miembro si también desea permitir un Flotador + un Complemento (las funciones miembro no permiten la promoción del argumento de la izquierda, ya que eso cambiaría la clase del objeto que está el destinatario de la invocación de la función miembro).

2

Las funciones y clases de Friend no infringen la encapsulación cuando intenta crear una abstracción o interfaz que debe abarcar físicamente varias clases o funciones de C++. Es por eso que amigo fue inventado.

Esos tipos de casos no aparecen a menudo, pero a veces se ve obligado a implementar una abstracción o interfaz con clases y funciones dispares. El ejemplo clásico es implementar algún tipo de clase de números complejos. A las funciones del operador no miembro se le da amistad a la clase principal de números complejos.

También recuerdo haber hecho esto al programar con CORBA en C++. CORBA me obligó a tener clases separadas para implementar servidores CORBA. Pero para una parte particular de nuestro software, necesitaba casarlos juntos como una sola interfaz. La amistad permitió que estas dos clases trabajaran juntas para proporcionar un servicio sin interrupciones a una parte de nuestro software.

Tener la capacidad de marcar una función de miembro en particular en otra clase como amigo de tu clase puede parecer aún más extraño, pero es solo una forma de controlar la amistad. En lugar de permitir que toda la otra clase "entre" como tu amigo, solo permites el acceso a una de sus funciones miembro. De nuevo, esto no es común, pero muy útil cuando lo necesite.

+1

+1 para "no violar". Sin embargo, es inútil en el caso de la mayoría de las clases numéricas como complejas, racionales, ... –

0

Un punto que considero relevante: las clases miembro tienen acceso a las partes privadas de la clase contenedora. Esto a veces puede ser una mejor alternativa a "amigo".

class A 
{ 
private: 
    int b; 
public: 
    class MemberNotFriend { 
    public: 
    static void test() { 
     A a; 
     a.b = 0; 
    } 
    }; 


}; 


void test() 
{ 
    A::MemberNotFriend::test(); 
} 
0

Aquí está un ejemplo sencillo, concreto de cómo estoy usando una función amigo:

Tengo un juego en el que cada objeto de sprites almacena su información como la posición X, Y como miembros privados. Sin embargo, deseo separar los objetos del juego de la representación: un objeto de juego no necesita los detalles exactos de cómo se representa. Un objeto del juego solo almacena el estado del juego, y este estado del juego se puede representar de diferentes maneras.

Por lo tanto, la clase de objeto del juego tiene una función de amigo: render(). La función render() se implementa fuera de la clase de objeto del juego, pero puede acceder a las posiciones X, Y posicionar a las entidades según sea necesario para representar el objeto del juego.

Cuestiones relacionadas