test solo significa saber quiere que porque pero mas hombre funciones cuando como busca amigo amigas algo c++ class language-lawyer friend access-rights

c++ - solo - me quiere como amigo pero me busca



¿Por qué un miembro de PRIVADO no puede ser un amigo de otra clase? (2)

class x { void xx() {} }; class y { friend void x::xx(); };

Esto resulta en un error como

error: la función de amigo ''xx'' es un miembro privado de ''x''

¿Por qué no puedo declarar que una función miembro privada sea amiga de otra clase?


Se supone que la idea de hacer que x::xx private es que x::xx es un detalle de implementación en el que otras clases no deberían confiar. No solo significa que x::xx no puede ser llamado por otras clases, significa, o más bien debería significar, que, por ejemplo, cambiar el nombre de x::xx a x::xy no debe romper nada que no sea la propia clase, y los amigos de la clase.

En su caso, cambiar el nombre de x::xx a x::xy causaría que la clase y tenga un error, aunque no sea amigo de x .

Una forma de evitar eso es hacer que y amigo de x , para que pueda acceder a private miembros private x . Entonces puede declarar x::xx como friend .

(Nota: la respuesta más directa a la pregunta "¿Por qué el compilador no permite esto?" Es "Porque el estándar no lo permite", lo que naturalmente conduce a la pregunta de seguimiento "¿Por qué el estándar no lo permite? ". Estoy tratando de responder esa pregunta de seguimiento.)


[class.friend]/9 :

Un nombre nominado por una declaración de amigo será accesible en el alcance de la clase que contiene la declaración de amigo.

La razón es bastante simple; private miembros private obedecerán una regla clara y definida:

Un miembro de una clase puede ser

  • private es decir, su nombre solo puede ser utilizado por miembros y amigos de la clase en la que se declara.

Permitir que los miembros privados sean nombrados en declaraciones dentro de clases no relacionadas violaría esta regla: permite que otra clase dependa de un detalle de implementación sin que se le permita explícitamente. Esto se vuelve problemático, por ejemplo, al cambiar el nombre, tipo o firma de un miembro privado, o al eliminarlo por completo; que está destinado a no romper la interfaz de esa clase.

Esto se puede sortear haciendo de la totalidad de x un amigo de y :

class x { void xx() {} }; class y { friend x; };

Demo