2012-08-15 28 views
5

Sé que se han hecho preguntas similares a esta antes, pero después de hacer mi investigación todavía tengo preguntas sobre el encabezado circular incluye.C++ header circular incluye

//FooA.h 
#ifndef H_FOOA 
#define H_FOOA 

#include "foob.h" 

class FooA{ 
    public: 
     FooB *fooB; 
}; 


//FooB.h 
#ifndef H_FOOB 
#define H_FOOB 

class FooA; 
class FooB{ 
    public: 
     FooA *fooA; 
}; 

Ahora, si tengo dos dependencias circulares, esta es la forma en que he visto a personas en stackoverflow solucionar el problema. Mi único problema con esto es que en mi main.cpp que debe incluir fooa.h primero y luego foob.h

//main.cpp the right way 
#include "fooa.h" 
#include "foob.h" 

//main.cpp that will surely get a compile error 
#include "foob.h" 
#include "fooa.h" 

Ahora mi pregunta es "¿Hay una manera de reenviar declarar estas clases de una manera que se ¿me permite no importarme el orden en que incluyo los archivos de encabezado en mi main.cpp? "

+0

Como las respuestas han señalado, se puede utilizar una declaración adelantada en ambos archivos. Si la situación fuera más complicada, podría '#incluir" fooa.h "' de 'foob.h', lo que garantizaría el orden de inclusión que desea. –

+0

No hay nada circular en las inclusiones en el código de ejemplo. Si agrega el # endif faltante todo está bien. ¿Qué error de compilación estás obteniendo? –

Respuesta

7

¿Hay alguna manera de reenviar declarar estas clases de una manera que me permita no importarme el orden en el que incluyo los archivos de encabezado en mi main.cpp?

ya que se trata de simples punteros solamente, se puede utilizar una declaración más adelante aquí en los dos casos:

FooA.h

#ifndef H_FOOA 
#define H_FOOA 

// #include "foob.h" << not needed! 
class FooB;  // << substitute with a forward declaration of FooB 

class FooA{ 
    public: 
     FooB *fooB; 
}; 
#endif 

FooB.h

#ifndef H_FOOB 
#define H_FOOB 

class FooA; 
class FooB{ 
    public: 
     FooA *fooA; 
}; 
#endif 
+0

@ user1600812 exactamente, y main puede incluir los archivos que necesita. Con este ejemplo, el orden no importará. – justin

+0

Supongo que olvidé mencionar eso en mi código específico. fooa.h forward se declara porque hay un par de punteros auto referidos en mi código. En mi caso específico, no creo que puedas hacerlo a tu manera porque yo sería el delantero declarando una clase dos veces. Sin embargo, en el ejemplo que hice arriba su solución funciona.Gracias. – user1600812

+0

@ user1600812 C++ permite múltiples declaraciones de reenvío (por ejemplo, en archivos separados). – justin

2

No tiene que preocuparse por el pedido porque fooa.h incluye foob.h, y foob.h tiene la declaración directa para FooA. Todo está correcto ya en tu código.

+1

Modulo de los # endif's faltantes, no hay problema con el código tal como fue publicado. Tampoco hay circularidad, lo que me hace sospechar que falta algo. –

1

Como ambas clases simplemente contienen un puntero, no es necesario que incluya el otro encabezado. Una declaración hacia delante servirá.

Cualquier código que realmente utiliza la otra clase tendrá necesita el encabezado, pero debe estar en un archivo cpp.

1

Use un forward declare en ambos archivos de encabezado.

¿Sabía que puede declararlo en la misma línea?

En "FooB.h"

class FooB{ 
    public: 
     class FooA *fooA; 
}; 

En "FooA.h"

class FooA { 
    public: 
     class FooB *fooB; 
}; 
+0

¿no hará referencias futuras a FooB :: FooA y FooA :: FooB respectivamente? –