¿Qué son las referencias cruzadas?
Llamamos referencias cruzadas a la situación en la que una clase A necesita hacer referencia a una clase B, y a su vez la clase B necesita hacer referencia la clase A.
Por ejemplo, supongamos que tenemos una aplicación encargada de la gestión de un taller, donde cada mecánico está arreglando un coche en cada momento. Tenemos que acceder desde el mecánico a su coche y desde el coche al mecánico asignado. Nuestros archivos de cabecera podrían ser algo así:
Mecanico.h
1 2 3 4 5 6 7 8 9 10 11 12 13 | #ifndef _MECANICO_H_ #define _MECANICO_H_ #include "Coche.h" class Mecanico { public: void arreglaCoche(Coche* coche); private: Coche* _coche; } #endif // _MECANICO_H_ |
Coche.h
1 2 3 4 5 6 7 8 9 10 11 12 13 | #ifndef _COCHE_H_ #define _COCHE_H_ #include "Mecanico.h" class Coche { public: void asignaMecanico(Mecanico* mecanico); private: Mecanico* _mecanico; } #endif // _COCHE_H_ |
Sin embargo, si intentamos compilar el ejemplo anterior obtendremos un error, ya el que el compilador intenta compilar una de las clases, por ejemplo la clase Mecanico. Se encuentra entonces con que para poder compilar la clase Mecanico, necesita la clase Coche. Entonces intenta compilar la clase Coche y se encuentra que ahora necesita la clase Mecanico, que todavía no está compilada. Al necesitarse las dos clases mútuamente, es imposible para el compilador continuar.
Solución
La forma en la que podemos corregir esto en C++ es bastante simple. Tendremos una de las clases exactamente igual a como la teníamos anteriormente. Por ejemplo, dejamos tal cual la clase Mecanico:
Mecanico.h
1 2 3 4 5 6 7 8 9 10 11 12 13 | #ifndef _MECANICO_H_ #define _MECANICO_H_ #include "Coche.h" class Mecanico { public: void arreglaCoche(Coche* coche); private: Coche* _coche; } #endif // _MECANICO_H_ |
En la clase Coche, sin embargo, introducimos un par de cambios. Por un lado, eliminamos el #include de Mecanico.h. Y por otro lado, declaramos que existe una clase Mecanico, pero no la definimos.
Coche.h
1 2 3 4 5 6 7 8 9 10 11 12 13 | #ifndef _COCHE_H_ #define _COCHE_H_ class Mecanico; class Coche { public: void asignaMecanico(Mecanico* mecanico); private: Mecanico* _mecanico; } #endif // _COCHE_H_ |
De esta forma podremos compilar nuestro programa salvando la problemática de las referencias cruzadas.
¡Saludos!