Confused...#include multiple header files

I've only recently began splitting my projects into separate source and header files, and running into regular linking errors.

All is fine putting function declarations in a single header.h, and defining them each in their own .cpp file.

But I always run into problems when I have more than one header file, for instance when I write a class.

So for instance, say I have:

Main.cpp
Functions.cpp // Some function definitions
Header.h // Some function declarations
Player.h // A class with player stats

In my header.h file, I have a function declaration that takes a Player object as an argument, something like:

void drawBoard(char arr[ROW][COL], Player& hero);

This produces a syntax error, presumably because it can't "see" the player class. So I add #include "Player.h" to the header.h

This seems to remedy the visibility of the class for the function definition (the red squiggly line is no more in VS!), but now I get a "error LNK2005: Player::Player(void) already defined", presumably because now in every subsequent .cpp file that has #include.h, the class is being defined multiple times. At least that is my understanding.

So what is the general way of doing this? Should a header file never include another header file? Should you have a main header, such as Header.h, that links everything together, and only ever have an #include "header.h" in your .cpp files?

Here's the structure of some code I was practising with, which gives me the above link error.

PLAYER.H

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef PLAYER_H
#define PLAYER_H

#include "Header.h"

class Player
{
	// Some player stats. Functions declared
	// and defined in the same file
}

#endif 


HEADER.H

1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef HEADER_H
#define HEADER_H

#include <iostream>
#include "Player.h"

static const int ROW = 3;
static const int COL = 3;

void initBoard(char (&arr)[ROW][COL]);
void drawBoard(char arr[ROW][COL], Player hero);

#endif 


DRAWBOARD.CPP

1
2
3
4
5
6
7
#include "Header.h"
#include "Player.h"

void drawBoard(char arr[ROW][COL], Player hero)
{
	// Code to display board
}


INITBOARD.CPP

1
2
3
4
5
6
#include "Header.h"

void initBoard(char (&arr)[ROW][COL])
{
	// Code to initialise board
}


MAIN.CPP

1
2
3
4
5
6
7
8
9
10
11
12
#include "Header.h"
//#include "Player.h"

int main()
{
	Player hero;
	char board[ROW][COL];

	initBoard(board);
	drawBoard(board, hero);

}




Last edited on
It's a circular include problem.

Header.h is including Player.h... and player.h is including Header.h. So which one gets included first?


There's no reason either header should be including the other. Player.h doesn't need to reference header.h at all. And header.h can get away with a forward declaration of the player class:

player.h
1
2
3
4
5
6
7
8
9
10
#ifndef PLAYER_H
#define PLAYER_H

// #include "Header.h" <- kill this

class Player
{
}

#endif  


header.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef HEADER_H
#define HEADER_H

#include <iostream>
// #include "Player.h"  <- kill this
class Player;  // <- replace with this

static const int ROW = 3;
static const int COL = 3;

void initBoard(char (&arr)[ROW][COL]);
void drawBoard(char arr[ROW][COL], Player hero);

#endif  


(You arguably don't need to #include <iostream> in header.h either, but whatever).



For more info on why/how this works and ways to avoid these kinds of problems entirely, see this thread:

http://www.cplusplus.com/forum/articles/10627/#msg49679
Last edited on
Your linker error is occurring because you have included function definitions in player.h (at least according to your comments).

Since player.h gets included in multiple .cpp files, those functions get compiled multiple times resulting in the the linker error you're seeing.

You should create a player.cpp file to contain the definitions for the functions declared in player.h.

So what is the general way of doing this?

- Never have function definitions in a .h file.
- For class functions defined in a .h file, put the class functions in a corresponding .cpp file.
- As a general rule, keep includes of other header files to a minimum in a .h file.

Thanks Disch, the two .h files referencing each other makes sense. That link is exactly what I was looking for.

Your linker error is occurring because you have included function definitions in player.h (at least according to your comments).


Yes! That is what it was. After fixing the includes as Disch described, I still had a link error. I had a constructor defined in Player.h. Once I commented that out it compiled. Thanks AbstractionAnon, I'll separate class definitions from the declarations.
Last edited on
Topic archived. No new replies allowed.