Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: SARGE553413 en 23 Febrero 2013, 02:38 am



Título: Duda con metodos friend con clases en distintos ficheros header (SOLUCIONADO)
Publicado por: SARGE553413 en 23 Febrero 2013, 02:38 am
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:

Código:
//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.



Título: Duda con metodos friend(SOLUCIONADO)
Publicado por: SARGE553413 en 24 Febrero 2013, 19:11 pm
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:
Código:
#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
Código:
#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

Código:
/* 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.