Question

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

server.h needs:
- socket.h

socket.h needs:
- game.h

The problem comes when I try to include socket.h into game.h, because socket.h has game.h included already. How do I solve these kind of problems?

Was it helpful?

Solution

The usual way, use #ifdef and #define in your header files

inside game.h:

#ifndef GAME_H
#define GAME_H

.. rest of your header file here

#endif

This way, the contents will be read multiple times, but only defined once.

Edit: Removed underscores at start and end of identifier per comments.

OTHER TIPS

The key is forward declaration. Take the stuff from game.h that is required in socket.h (or vice-versa) and forward-declare it in yet another header, e.g. game_forwards.h. As an example, consider the following:

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

Clearly, for this to work, it's important to separate interface and implementation.

In addition to the techniques (forward definition and read-once headers), you need to work out why your socket header requires anything from the game header, and package your system into modules with a single dependency order. There shouldn't be any reason a socket class needs to know about what game it is being used for.

For completeness, another alternative is:

#pragma once 

at the top of the file.

This has the advantage that the file is not opened repeatedly, saving compile time.

It has the disadvantage of not being standard, so not all compilers support it. Works reliably in Visual C++.

There's no elegant way around it that I can think of - your best bet is to forward-define the functions that will actually be used. So, if game.h only uses the connect() function from socket.h, add this line to game.h:

void connect();

And remove the socket.h import. Of course if the signature of connect() changes you'll need to remember to update the forward definition too, so this solution is far from ideal. If you possibly can, modify the design to avoid the circular dependencies.

If game.h just needs to know about a class in socket.h, forward define it like this:

class Socket;

There are some caveats when it comes to inline functions and member objects, see The C++ FAQ Lite.

@lassevk, shouldn't that be "the header file will be opened several times, but the preprocessor will only read the contents of the file between the #ifndef and #endif once, during the first read. After then the preprocessor will ignore bewteen the PP macros because _GAME_H has been defined."

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top