Cuando el compilador comienza compilar el código (por lo general de la parte superior) y se encuentra con esta línea:
friend void B::fB(A& a);
- en este punto, el compilador no sabe nada de información tipo de B por lo que arroja un error ('B': no es una clase o nombre de espacio de nombres).
por la declaración directa de la clase B, el compilador sabe sobre el tipo de B es la Clase por adelantado a su declaración real con todos los miembros.
ejecución de código a continuación después de la declaración de avance de la clase B.
///////////////
class B;
class A
{
public:
friend void B::fB(A& a);
void fA(){};
};
class B
{
public:
void fB(A& a){};
void fB2(A& a){};
};
Aún error !!!
porque la declaración directa es solo una declaración de un identificador para el cual el programador aún no ha dado una definición completa. por lo que el compilador necesita una definición completa de B antes de la clase A.
Nota: la definición de clase A depende del tipo de B y también la definición de B (es decir, B :: fB) para que la declaración directa no pueda resolverse, complete la definición de clase B tiene que definir antes de la clase A.
4 ejecuta este código
////////
class B
{
public:
void fB(A& a){};
void fB2(A& a){};
};
class A
{
public:
friend void B::fB(A& a);
void fA(){}
};
Aún error !!!
debido a las funciones miembro de la clase B fB & FB2 tener argumentos de tipo A, pero el compilador no tiene ni idea sobre información de tipo de un modo mediante declaración delante de la clase A, podemos dejar que el compilador sabe acerca de información de tipo A. Nota: Clase definición B sólo depende del tipo a no los miembros de una manera que la declaración de avance de un paso determinación 4.
- código final
////// //////////////////
class A; // forward declaration of A needed by B
class B
{
public:
void fB(A& a);
};
class A
{
int i;
public:
friend void fA(A& a); //specifying function fA as a friend of A, fA is not member function of A
friend void B::fB(A& a); //specifying B class member function fB as a friend of A
};
// fA is Friend function of A
void fA(A& a)
{
a.i = 11; // accessing and modifying Class A private member i
cout<<a.i<<endl;
}
// B::fB should be defined after class A definition only because this member function can access Class A members
void B::fB(A& a)
{
a.i = 22; // accessing and modifying Class A private member i in Class B member function fB
cout<<a.i<<endl;
}
int main()
{
A a;
fA(a); // calling friend function of class A
B b;
b.fB(a); // calling B class member function fB, B:fB is friend of class A
return 0;
}
6 Ejercicio:
// Cyclic dependency
#include<iostream>
using namespace std;
class A;
class B
{
public:
void fB(A& a);
friend void A::fA(B& b); //specifying class A's member function fA as a friend of B
};
class A
{
int i;
public:
void fA(B& b);
friend void B::fB(A& a); //specifying class B's member function fB as a friend of A
};
int main()
{
return 0;
}
Pero si en fB (A & A) Yo uso una para acceder a una variable en, por ejemplo, a.variable; eso sería ilegal porque A no se había definido aún. – ipkiss
@ipkiss sí, porque entonces necesitaría la definición completa si lo hace en la declaración de la clase de encabezado. Pero si lo hizo en un archivo de implementación separado, puede incluir la declaración completa de A. – juanchopanza