Pregunta

game.h needs:
- packet.h
- socket.h

server.h needs:
- socket.h

socket.h needs:
- game.h

El problema viene cuando intento de incluir en socket.h game.h, porque tiene socket.h game.h ya incluido. ¿Cómo puedo solucionar este tipo de problemas?

¿Fue útil?

Solución

La forma habitual, usar #ifdef y # define en sus archivos de cabecera

Dentro de game.h:

#ifndef GAME_H
#define GAME_H

.. rest of your header file here

#endif

De esta manera, el contenido será leído varias veces, pero sólo define una vez.

Editar . Guiones retirada al principio y al final del identificador por los comentarios

Otros consejos

La clave es la declaración hacia adelante. Tome las cosas de game.h que se requiere en socket.h (o viceversa) y con visión de declarar que en otro encabezado, por ejemplo, game_forwards.h. Como ejemplo, considere lo siguiente:

// game_fwd.h

#ifndef GAME_FWD_H
#define GAME_FWD_H

class game;

#endif // ndef GAME_FWD_H

// game.h

#ifndef GAME_H
#define GAME_H

#include "socket.h"

class game {
    socket* m_sck;
};

#endif // ndef GAME_H

// socket.h

#ifndef SOCKET_H
#define SOCKET_H

#include "game_fwd.h"

class socket {
    game* m_game;
};

#endif // ndef SOCKET_H

Es evidente que, para que esto funcione, es importante separar la interfaz y la implementación.

Además de las técnicas (definición hacia adelante y lectura vez cabeceras), es necesario entender por qué su cabecera zócalo requiere nada de la cabecera del juego, y el paquete de su sistema en módulos con una sola orden de dependencia. No debería haber ninguna razón por la toma de una clase necesita saber de qué juego se está utilizando para.

Para completar, otra alternativa es:

#pragma once 

en la parte superior del archivo.

Esto tiene la ventaja de que el archivo no se abre en varias ocasiones, el ahorro de tiempo de compilación.

Tiene la desventaja de no ser estándar, por lo que no todos los compiladores soportan. Funciona de forma fiable en Visual C ++.

No hay manera elegante a su alrededor que puedo imaginar - su mejor opción es reenviar a definir las funciones que realmente se utilizan. Por lo tanto, si game.h sólo utiliza la función connect () desde socket.h, añadir esta línea a game.h:

void connect();

Y eliminar la importación socket.h. Por supuesto, si la firma de connect () cambia tendrá que acordarse de actualizar la definición adelante también, por lo que esta solución está lejos de ser ideal. Si puede, modificar el diseño para evitar las dependencias circulares.

Si game.h sólo necesita saber acerca de una clase en socket.h, hacia adelante definirlo así:

class Socket;

Hay algunas advertencias cuando se trata de inline funciones y objetos miembro, vea El C ++ FAQ Lite .

@lassevk, no debe ser que "el archivo de cabecera se abrirá varias veces, pero el preprocesador sólo se leerá el contenido del archivo entre el #ifndef y #ENDIF una vez, durante la primera lectura. Después de entonces el preprocesador ignorará bewteen las macros PP porque _GAME_H se ha definido ".

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top