0

I'm writing code for a game of tic tac toe which includes a player abstract class. the abstract class extends to a HumanPlayer class and a ComputerPlayer interface which itself extends a RandomPlayer subclass. In the program there is a Game class header as follows

#ifndef GAME_HPP_
#define GAME_HPP_

#include "HumanPlayer.cpp"
#include "RandomPlayer.cpp"
class Game{
/*functions and variables go here*/
};

#endif /* GAME_HPP_ */

Both HumanPlayer and RandomPlayer eventually include Player.hpp and Player.hpp includes the Board class Board.cpp. Essentially whenever this is compiled, Player.hpp is included twice and so Board.cpp is included twice. Every header file is contained in include guards yet in Board.cpp and Game.cpp I'm still getting "first defined here" errors on every member function. How do I get rid of those errors?

  • Note that include guards prevent multiple inclusion within the same [translation unit](https://stackoverflow.com/questions/1106149/what-is-a-translation-unit-in-c). If multiple translation units include the same headers there will be duplication. – user4581301 Dec 07 '20 at 22:38
  • @TonyTannous why delete the answer? It was good. – Fantastic Mr Fox Dec 07 '20 at 23:01
  • @FantasticMrFox I deleted and upvoted yours. Yours look better to the eye. I though suggest you edit and mention how he breaks the ODR by including .cpp as I think he wants to know why hes getting errors. – Tony Tannous Dec 07 '20 at 23:28

1 Answers1

2

In c++ there is never a reason to include a cpp file directly. The idea is to include headers, this is because of the compilation process. Here is a quick overview:

  1. Preprocessor
  2. Compilation
  3. Linking

The idea is that your cpp files will be compiled separately, then linked together. For example, imagine something like this:

somefunc.hpp

void somefunc(); // declaration of a function

somefunc.cpp

#include "somefunc.hpp"

void somefunc() {  // definition of a function  
}

funcuser.cpp

#include "somefunc.hpp" // We include the header to get the declaration for 
                        // compile time

void otherfunc() {
    somefunc(); // We can call the function only knowing its declaration, at
                // link time we link this function to its definition allowing
                // it to be used.
}

This is a rough overview, and you need to change your code to a similar mechanism. But you may need to learn more about it, for which I recommend you look at:

The Definitive C++ Book Guide and List

Because you are including multiple definitions in a single translation unit, you are breaking the One Definition Rule (ODR). This occurs from including the definition of the items in HumanPlayer.cpp and RandomPlayer.cpp in Game.hpp. These definitions will then be included everywhere that Game.hpp is included. Since there is now more then one definition, you have broken the ODR.

Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175