Você está na página 1de 15

Funciones y Clases

Amigas en C++
Dr. Oldemar Rodrguez Rojas
Escuela de Informtica
Universidad de Nacional
INTRODUCCIN A LAS
FUNCIONES AMIGAS
Habr momentos en los que se quiera que una
funcin tenga acceso a los miembros privados
de una clase sin que esa funcin sea realmente
un miembro de esa clase.
De cara a esto, C++ soporta las funciones
amigas. Una funcin amiga no es un miembro
de una clase, pero tiene acceso a sus
elementos privados.
Para qu sirven las funciones amigas?
Dos motivos por los que las funciones amigas son tiles
tienen que ver con la sobrecarga de operadores y la
creacin de ciertos tipos de funciones de E/S.
Una tercera razn para las funciones amigas es que
habr momentos en los que una funcin tenga acceso a
los miembros privados de dos o ms clases diferentes.
Este uso es el que se examina aqu. Una funcin amiga
se define como una funcin no miembro normal. Sin
embargo, dentro de la declaracin de clase para la que
ser una funcin amiga, est tambin incluido su
prototipo, precedido por la palabra clave friend.
Para entender cmo funciona, examine este breve
programa:
#include <iostream.h> int main() {
#include <conio.h> myclass ob1(10,2),ob2(13,3);
if(isfactor(ob1))
cout << "2 es un factor de 10\n";
class myclass {
else
int n, d;
cout << "2 no es un factor de
public: 10\n";
myclass(int i,int j) {n=i;d=j;} if(isfactor(ob2))
// declara una funcin amiga de cout << "3 es un factor de 13\n";
myclass else
friend int isfactor(myclass ob); cout << "3 no es un factor de
13\n";
};
char ch=getch();
return 0;
int isfactor(myclass ob) { }
if(!(ob.n % ob.d))
return 1;
else
return 0;
}
En este ejemplo, myclass declara su funcin constructora y
la funcin amiga isfactor() dentro de su declaracin de
clase. Debido a que isfactor() es una funcin amiga de
myclass, isfactor() tiene acceso a sus reas privadas. Esto
es por lo que dentro de isfactor(), es posible referirse
directamente a ob.n y ob.d.

Es importante entender que una funcin amiga no es un


miembro de la clase de la que es amiga. Por lo tanto, no es
posible llamar a una funcin amiga usando un nombre de
objeto y un operador de acceso a miembro de clase (un
punto o flecha).

Por ejemplo, suponiendo el ejemplo anterior, esta


sentencia est mal:
ob1.isfactor(); // ERROR
Las funciones amigas se llaman igual que las funciones
normales.

Aunque una funcin amiga tiene conocimiento de los


elementos privados de la clase de la que es amiga, slo
puede acceder a ellos a travs de un objeto de la clase. Es
decir, a diferencia de un miembro de myclass, que se
pueden referir directamente a n o d, una funcin amiga
puede acceder a estas variables slo en conjuncin con un
objeto que est declarado dentro o pasado a la funcin
amiga.

Debido a que las funciones amigas no son miembros de


una clase, normalmente se le pasarn uno o ms objetos
de la clase para la que estn definidas.
Una funcin amiga no es miembro y no se puede calificar
mediante un nombre de objeto. Se tiene que llamar como
una funcin normal.
Una funcin amiga no se hereda. Es decir, cuando una
clase base incluye una funcin amiga, la funcin amiga no
es una funcin amiga de la clase derivada.
Otro punto importante sobre las funciones amigas es que
una funcin amiga puede ser amiga de ms de una clase.
Un uso comn (y bueno) de una funcin amiga se da
cuando dos tipos diferentes de clases tienen alguna
cantidad en comn que hay que comparar. Por ejemplo,
considere el siguiente programa, que crea una clase
llamada car y una clase llamada truck, cada una
conteniendo, como una variable privada, la velocidad del
vehculo que representa, veamos el siguiente ejemplo:
Esto permite implementar relaciones de Asociacin.
#include <iostream.h>
#include <conio.h>
class truck; // una referencia anticipada

class car {
int passengers;
int speed;
public:
car(int p,int s) {passengers=p;speed=s;}
friend int sp_greater(car c, truck t);
};

class truck {
int weight;
int speed;
public:
truck(int w,int s) {weight=w;speed=s;}
friend int sp_greater(car c, truck t);
};

int sp_greater(car c,truck t) {


return c.speed-t.speed;
}
int main() {
int t;
car c1(6,55),c2(2,130);
truck t1(10000,55), t2(20000,72);
cout << "Comparando el y tl:\n";
t=sp_greater(c1,t1);
if(t<0)
cout <<"El camin es ms rpido. \n";
else
if(t==0)
cout << "La velocidad del coche y del camin es la misma.\n";
else
cout << "El coche es ms rpido.\n";
cout << "\nComparando c2 y t2:\n";
t=sp_greater(c2,t2);
if(t<0)
cout << "El camin es ms rpido.\n";
else
if(t==0)
cout << "La velocidad del coche y del camin es la misma.\n";
else
cout << "El coche es ms rpido.\n";
char ch=getch(); return 0;
}
Una funcin puede ser
miembro de una clase y amiga
de otra.

Veamos el siguiente ejemplo:


#include <iostream.h>
#include <conio.h>
class truck; // una referencia anticipada

class car {
int passengers;
int speed;
public:
car(int p,int s) {passengers=p;speed=s;}
int sp_greater(truck t);
};

class truck {
int weight;
int speed;
public:
truck(int w,int s) {weight=w;speed=s;}
friend int car::sp_greater(truck t);
};

int car::sp_greater(truck t) {
return speed - t.speed;
}
int main() {
int t;
car c1(6,55),c2(2,130);
truck t1(10000,55), t2(20000,72);

cout << "Comparando el y tl:\n";


t=c1.sp_greater(t1);
if(t<0)
cout <<"El camin es ms rpido. \n";
else
if(t==0)
cout << "La velocidad del coche y del camin es la misma.\n";
else
cout << "El coche es ms rpido.\n";

cout << "\nComparando c2 y t2:\n";


t=c2.sp_greater(t2);
if(t<0)
cout << "El camin es ms rpido.\n";
else
if(t==0)
cout << "La velocidad del coche y del camin es la misma.\n";
else
cout << "El coche es ms rpido.\n";
char ch=getch(); return 0;
}
Clases Amigas
El caso ms comn de amistad se aplica a clases completas.
El modificador friend puede aplicarse a clases o funciones para inhibir
el sistema de proteccin.
Las relaciones de "amistad" entre clases son parecidas a las amistades
entre personas:
La amistad no puede transferirse, si A es amigo de B, y B es amigo de C, esto no
implica que A sea amigo de C. (La famosa frase: "los amigos de mis amigos son mis
amigos" es falsa en C++, y probablemente tambin en la vida real).

La amistad no puede heredarse. Si A es amigo de B, y C es una clase derivada de B,


A no es amigo de C. (Los hijos de mis amigos, no tienen por qu ser amigos mos. De
nuevo, el smil es casi perfecto).

La amistad no es simtrica. Si A es amigo de B, B no tiene por qu ser amigo de A.


(En la vida real, una situacin como esta har peligrar la amistad de A con B, pero de
nuevo me temo que en realidad se trata de una situacin muy frecuente, y
normalmente A no sabe que B no se considera su amigo).
#include <iostream>
using namespace std;

class Amigable {
private:
int secreto;
friend void FuncionAmiga(Amigable& o);
friend class Amiga;
};

class Amiga {
public:
void mirar(Amigable& o) {
o.secreto = 120;
cout << o.secreto << endl;
}
};
void FuncionAmiga(Amigable& o) {
o.secreto = 121;
cout << o.secreto << endl;
}

// Programa principal
int main() {
Amiga amiga;
Amigable amigable;
amiga.mirar(amigable);
FuncionAmiga(amigable);
system("pause");
system("cls");
return 0;
}

<Ver Ej1.CPP>

Você também pode gostar