|
|
Ya
sabemos que los miembros privados de una clase no
son accesibles para funciones y clases exteriores a
dicha clase.
Esto
es un concepto de POO, el encapsulamiento hace que
cada objeto se comporte de un modo autónomo y que lo que
pase en su interior sea invisible para el resto de objetos. Cada
objeto sólo responde a ciertos mensajes y proporciona
determinadas salidas.
Pero,
en ciertas ocasiones, querremos poder acceder a determinados miembros
privados de un objeto de una clase desde otros objetos de clases
diferentes. C++ proporciona un mecanismo para sortear el sistema
de protección.
|
|
|
Ya
se ha visto anteriormente que declarar como privadas las
variables miembro de una clase ofrece muchas ventajas.
De todos modos, en algunos casos, puede suceder que dos clases vayan
a trabajar conjuntamente con los mismos datos, y utilizar las funciones
públicas de acceso a esos datos no es la manera más
eficiente de hacerlo; conviene recordar que llamar a una función
tiene un coste y que es mucho más eficiente acceder directamente
a una variable. Ésta no es la única limitación
de las funciones miembro, ya que una función
sólo puede ser miembro de una única clase.
Además una función miembro convencional sólo
puede actuar directamente sobre un único objeto de la clase
(su argumento implícito, que es el objeto con el que ha sido
llamada por medio del operador punto (.) o flecha (->), como
por ejemplo en c1.Ingreso(10000)). Para que actúe
sobre un segundo o un tercer objeto -por ejemplo, para hacer transferencias-
hay que pasárselos como argumentos.
Se
puede concluir que a pesar de las grandes ventajas que tiene el
encapsulación, en muchas ocasiones es necesario
dotar a la programación orientada a objetos de una mayor
flexibilidad. Esto se consigue por medio de las funciones
friend. Una función friend de
una clase es una función que no pertenece a la clase,
pero que tiene permiso para acceder a sus variables
y funciones miembro privadas por medio de los operadores punto (.)
y flecha (->), sin tener que recurrir a las funciones miembro
públicas de la clase. Si una clase se declara friend
de otra, todas sus funciones miembro son friend
de esta segunda clase. El carácter de friend puede
restringirse a funciones concretas, que pueden ser miembro de alguna
clase o pueden ser funciones generales que no pertenecen a ninguna
clase..
Para
declarar una función o una clase como
friend de otra clase, es necesario hacerlo en la declaración
de la clase que debe autorizar el acceso a sus datos privados.
Esto se puede hacer de forma indiferente en la zona de los datos
o en la de los datos privados. Un ejemplo de declaración
de una clase friend podría ser el que sigue:
|
|
|
Es
muy importante tener en cuenta que esta relación funciona
sólo en una dirección, es decir, las funciones miembro
de la clase Amiga pueden acceder a las variables privadas
de la clase Cualquiera, por ejemplo a la variable
entera secreto, pero esto no es cierto en sentido
inverso: las funciones miembro de la clase Cualquiera
no puede acceder a un dato privado de la clase Amiga.
Si
se quiere que varias clases tengan acceso mutuo a todas las variables
y funciones miembro privadas, cada una debe declararse como
friend en todas las demás, para conseguir una relación
recíproca.
Otro
aspecto que hay que mencionar es que al definir una clase como
friend no se está haciendo friend a
todas las clases que se deriven de ella (esto se entenderá
al llegar al capítulo de la herencia).
Hay
que tener en cuenta que para que una función que no es miembro
de una clase pueda recibir como argumentos explícitos objetos
de esa clase, debe ser declarada friend de esa clase.
Un ejemplo de una función friend es el que
sigue:
|
|