Hola a todos, expongo mi duda:
Tengo dos clases A y B, ambas tienen por un lado su fichero de cabecera ("A.h") y su fichero de definición o como lo queráis llamar ("A.cpp"). Por tanto están en ficheros separados y se enlazan con includes.
Lo que quiero es definir un método en la clase B que pueda acceder a los atributos private de la clase A, y para ello voy a usar un método friend pero no se como enlazar los ficheros para que se pueda hacer. Quiero hacer algo como:
//Dfinicion de la clase B:
....
....
void B::metodoEnCuestion(A *a){
a->n=25;
}
//Declaracion de la clase A:
....
private: int n;
....
friend void B::metodoEnCuestion(A *);
....
He buscado en varias webs y en google, y encuentro cosas de métodos friend pero no encuentro como hacerlo con 2 clases en distintos ficheros con includes.
El caso es que lo he intentado de varias maneras pero no se como hacerlo, me ayuda alguien por favor?
Muchas gracias.
Hola de nuevo, en vista de que no contestaba nadie he seguido "haciendo experimentos" hasta que he dado con la solución. La expongo a continuación, AVISO creo que quedará un post muy largo, igual os aburrís, ahí va:
Recordando el problema, tenemos 2 clases independientes, cada una son su fichero *.h y su fichero .*cpp respectivamente, llamemoslas A y B, queremos que B tenga un, y solo un método capaz de acceder a las partes privadas de A:
Comenzamos con la declaración de A:
#include "B.h"
/* Incluimos el fichero de cabecera en A para que el compilador conozca la clase B
y sus métodos, de lo contrario no podríamos hacer ninguna referencia a los métodos de B, como si fuésemos a hacer una relación de agregación*/
#ifndef A_H
#define A_H 1
class A{
private:
int n; //por ejemplo..
friend void B::hola(A *);
/* le decimos a A que este método de B podrá acceder a sus partes privadas*/
/* como se puede observar, esta declaración es private, creo que es lo mas lógico ya que se trata de que solo el metodo hola de B pueda acceder a A, luego debería ser información "restringida" para las demás clases, aunque es posible que de lo mismo ponerla public o private, no lo sé :P */
....
public:
....
etc.
};
#endif
/*Nota: el *.cpp de A no lo pongo porque no hace falta, se hace todo igual que siempre*/
Veamos que hacer en B
#ifndef B_H
#define B_H 1
/*Dentro de B, avisamos al compilador de que hay una clase llamada A. Como estamos en la parte de declaración, no es necesario saber ahora mismo como es o que tiene la clase A. IMPORTANTE: no poner #include "B.h" porque entonces el compilador da error, me imagino que se forma una especie de bucle con los includes, nunca paran de incluirse mutuamente*/
class A;
class B{
private:
...
...
public:
...
void hola(A *);
/*es importante que el método en cuestión reciba como argumento un puntero a A, me explico:
el compilador siempre sabe como pasar una dirección ya que es de tamaño fijo, sin importar el tipo o a lo que apunte, sin embargo si intentamos pasar el objeto en sí, el compilador necesitará saber como es el objeto "por dentro", y no podemos darle esa información ya que no podemos usar #include "A.h" */
#endif
Hasta aquí el *.h de B, veamos ahora que hacer en su *.cpp
/* B.cpp */
#include "B.h" //lo tipico
#include "A.h" /*aquí si que podemos ponerlo sin que el compilador llore, y nos hace falta porque vamos a hacer referencia a atributos etc. private de A, luego el compilador deber saber como es A*/
void B::hola(A *a){
a->n=25; //correcto, y 'n' en A es private ;)
}
Y eso es todo, espero le sirva a alguien.
Saludos.