2009-06-15 30 views
14

Soy nuevo en C++, por lo que esta pregunta puede ser básica:Dos clases que se refieren entre sí

Tengo dos clases que deben referirse entre sí. Cada uno está en su propio archivo de encabezado, y # include es el archivo de encabezado del otro. Cuando intento compilar, obtengo el error "ISO C++ prohíbe la declaración de 'Foo' sin tipo" para una de las clases. Si cambio las cosas para que el encabezado opuesto sea analizado primero, obtengo el mismo error con la otra clase.

¿Es posible en C++ tener dos clases que necesiten referencias entre sí?

Para más detalles: Tengo una clase de "Aplicación" y una clase "Ventana". La aplicación debe hacer referencia a la ventana para hacer que la ventana. Window tiene un botón que devuelve la llamada a la aplicación, por lo que necesita una referencia a la aplicación. Si no puedo hacer que dos clases se refieran entre sí, ¿hay una mejor manera de implementar esto?

+2

Cabe señalar que las dependencias mutuas deben evitarse cuando sea posible. ¿Tendría sentido factorizar la funcionalidad que los botones llaman en la aplicación en un objeto controlador independiente? –

+0

Este problema lo encuentro a menudo en mis pequeños juegos. Tengo un objeto World que contiene objetos del juego que necesitan hacer referencia al objeto World para, p. Ej. Detección de colisiones. No he encontrado una buena manera de refactorizar eso. (Y por cierto, despertando una discusión de 7 años para ganarme algún tipo de insignia) – Johan

Respuesta

27

Puede usar las declaraciones de reenvío en los archivos de encabezado para evitar las dependencias circulares siempre que no tenga dependencias de implementación en los encabezados. En Window.h, añada esta línea:

class App; 

en App.h, añada esta línea:

class Window; 

Añadir estas líneas antes de que las definiciones de clases.

Luego, en los archivos fuente, puede incluir los encabezados para las definiciones de clase reales.

Si sus definiciones de clase hacen referencia a miembros de la otra clase (por ejemplo, en líneas), entonces deben moverse al archivo fuente (ya no en línea).

8

La declaración directa es el camino a seguir.

Si está utilizando punteros \ referencia en el encabezado de clase, la declaración de reenvío en ambos lados funcionaría para usted.

Si está creando el objeto como miembro de la clase, debe incluir el encabezado. (La declaración de reenvío no funcionará ya que el compilador necesita una definición de clase para conocer el tamaño).

Refer C++ FAQ for solving such senario:

Si va a crear la ventana como miembro continuación incluyen la cabecera de la ventana de la aplicación, pero al mismo intervalo de tiempo no debe incluir un encabezado de la aplicación. Usa la combinación de puntero a la aplicación y la declaración hacia adelante allí.

Cuestiones relacionadas