Pergunta

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

server.h needs:
- socket.h

socket.h needs:
- game.h

O problema surge quando eu tento incluir socket.h em game.h, porque socket.h tem game.h já incluído. Como faço para resolver este tipo de problemas?

Foi útil?

Solução

A maneira usual, use #ifdef e #define em seus arquivos de cabeçalho

game.h dentro:

#ifndef GAME_H
#define GAME_H

.. rest of your header file here

#endif

Desta forma, o conteúdo será lido várias vezes, mas apenas definido uma vez.

Editar :. Sublinhados removidos em início e fim do identificador por comentários

Outras dicas

A chave é a declaração para a frente. Levar o material a partir de game.h que é necessário em socket.h (ou vice-versa) e para a frente-declarar que em ainda outro cabeçalho, por exemplo game_forwards.h. Como exemplo, considere o seguinte:

// 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

Claramente, para que isso funcione, é importante interface e implementação separada.

Além das técnicas (definição para a frente e de leitura uma vez cabeçalhos), você precisa trabalhar fora porque seu cabeçalho tomada requer qualquer coisa, desde o cabeçalho jogo, e empacotar seu sistema em módulos com uma única ordem de dependência. Não deve haver qualquer razão uma classe tomada precisa saber sobre o jogo que está a ser utilizado.

Para completar, uma outra alternativa é:

#pragma once 

no topo do arquivo.

Isto tem a vantagem de que o arquivo não é aberto repetidamente, poupando tempo de compilação.

Ele tem a desvantagem de não ser padrão, de modo que nem todos os compiladores apoiá-lo. Funciona de forma confiável no Visual C ++.

Não há nenhuma maneira elegante em torno dele que eu posso pensar - sua melhor aposta é de transmitir-definir as funções que serão realmente utilizados. Então, se game.h só usa a função connect () de socket.h, adicionar esta linha ao game.h:

void connect();

E remover a importação socket.h. Claro, se a assinatura do connect () muda você precisa se lembrar de atualizar a definição para a frente também, então esta solução está longe de ser ideal. Se você possivelmente pode, modificar o projeto para evitar as dependências circulares.

Se game.h só precisa saber sobre uma classe em socket.h, frente defini-lo como este:

class Socket;

Existem algumas ressalvas quando se trata de funções embutidas e objetos membro, consulte A C ++ FAQ Lite .

@lassevk, não deve que ser "o arquivo de cabeçalho será aberta várias vezes, mas o pré-processador só irá ler o conteúdo do arquivo entre o #ifndef e #endif uma vez, durante a primeira leitura. Depois, em seguida, o pré-processador irá ignorar bewteen as macros PP porque _GAME_H foi definido ".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top