2009-12-03 11 views
19

Así que tengo una clase A, donde quiero llamar a algunas funciones de clase B. Entonces incluyo "b.h". Pero, en la clase B, quiero llamar a una función de clase A. Si incluyo "a.h", termina en un ciclo infinito, ¿verdad? ¿Qué puedo hacer al respecto?¿Pueden dos clases verse unas a otras usando C++?

Respuesta

26

Cada clase (A y B) debe tener un archivo de cabecera y un archivo de implementación.

Cada archivo de cabecera (por ejemplo A.h) no debe incluir otro archivo de cabecera (por ejemplo B.h) pero puede incluir una referencia hacia adelante a la otra clase (por ejemplo, una declaración como class B;), y luego se puede utilizar punteros y/o referencias a la otra clase en su declaración (por ejemplo, class A puede contener B* como un miembro de datos y/o como un parámetro de método).

Cada archivo CPP (por ejemplo, A.cpp) puede incluir más de un archivo de encabezado (por ejemplo, A.h y B.h). Se recomienda que cada archivo CPP incluya primero su propio archivo de encabezado (por ejemplo, A.cpp debe incluir A.h y luego B.h, mientras que B.cpp debe incluir B.h y luego A.h).

Cada archivo de encabezado solo debe contener la declaración y no la definición de la clase: por ejemplo, listará las firmas de los métodos de la clase, pero no el método bodies/implementations (los cuerpos/implementaciones del método estarán en el archivo .cpp, no en el archivo de encabezado). Debido a que los archivos de encabezado no contienen detalles de implementación, por lo tanto, no dependen (no necesitan ver) los detalles de otras clases; a lo sumo necesitan saber que, por ejemplo, B es el nombre de una clase: que puede obtener de una declaración directa, en lugar de incluir un archivo de encabezado en otro archivo de encabezado.

35

Ponga solo declaraciones de función de miembro en archivos de encabezado (.h) y coloque definiciones de función de miembro en archivos de implementación (.cpp). Entonces, sus archivos de encabezado no necesitan incluirse entre sí, y puede incluir ambos encabezados en cualquiera de los archivos de implementación.

Para casos, es necesario hacer referencia a la otra clase de firmas de los miembros, así, se puede utilizar una declaración adelantada:

class A; 

Esto le permite utilizar puntero y de referencia tipos (A* y A&), aunque no A sí mismo. Tampoco te permite llamar a miembros.

Ejemplo:

// a.h 
struct B; // forward declaration 

struct A { 
    void foo(B* b); // pointers and references to forward-declared classes are ok 
}; 


// b.h 
struct A; // forward declaration 

struct B { 
    void bar(A& a); // pointers and references to forward-declared classes are ok 
}; 


// a.cpp 
#include "a.h" 
#include "b.h" 

void A::foo(B* b) { 
    b->bar(*this); // full declaration of B visible, ok to call members now 
} 


// b.cpp 
#include "a.h" 
#include "b.h" 

void B::bar(A& a) { 
    a.foo(this); // full declaration of A visible, ok to call members now 
} 
-7

Intente poner #ifndef, #define y #endif alrededor de sus archivos .h.

+1

Esta publicación tampoco responde la pregunta .. –

Cuestiones relacionadas