0

So I 3 classes as follows:

class Weapon {
    char* name;
    Target target;
    int hitStrength;
public:
    Methods...
};

class Player {
    char* name;
    int level;
    int life;
    int strength;
    Weapon weapon;
    int location;
public:
    Methods...
};

class Game {
    int maxPlayers;
    Player** players;
public: 
    Methods...
};

I am having trouble with includes. I have a main.cpp file which has the following includes:

#include "Game.h"
#include <iostream>
using namespace std;

However, when I try to build the program I get the following error:

In file included from C:\Users\Name\CLionProjects\Call Of Matam Duties\Player.h:8:0,
             from C:\Users\Name\CLionProjects\Call Of Matam Duties\Game.h:8,
             from C:\Users\Name\CLionProjects\Call Of Matam Duties\main.cpp:1:
C:\Users\Name\CLionProjects\Call Of Matam Duties\Weapon.h:30:12: error: 'ostream' does not name a type
 friend ostream& operator<< (ostream& os, const Weapon& w);`

To mention:
Player.cpp includes Player.h; Weapon.cpp includes Weapon.h; Game.cpp includes Game.h; Game.h includes Player.h and Weapon.h.

Is it correct?

How can I fix this?

If you need more information, let me know.

Evg
  • 25,259
  • 5
  • 41
  • 83
  • 2
    To use anything from `` in a header (including declaring functions like `operator<<(std::ostream&, your_type)` as a friend) it is advisable to `#include ` in that header, so the header works as intended regardless of whether or not `` has been included elsewhere. Also, refer to `ostream` as `std::ostream` since it is a really bad idea to employ `using namespace std` in any header file. – Peter Aug 18 '18 at 07:11
  • 1
    If _only_ a forward declaration is needed in the header, `#include ` can (or should) be used. – Evg Aug 18 '18 at 07:18
  • please check the edit, and update it accordingly. I hope you did not `#include ` *after* `using namespace`. You should not – max630 Aug 18 '18 at 07:26
  • Thank you for your answer! Do I need to add `include ` in every .h and .cpp file? or just .cpp files? – kidneyThief Aug 18 '18 at 07:30

3 Answers3

3

You should include <iostream> in Weapon.h since that is where it is needed. Each header file should be compilable by itself, it should not depend on being placed after other includes.

There's a good practice to avoid errors like this. You have Player.cpp includes Player.h; Weapon.cpp includes Weapon.h; Game.cpp includes Game.h. That's good, but make sure that the first header file that Player.cpp includes is Player.h and the same with all the other header files. If that change causes any compilation errors then that indicates that your header files are wrong because they can't be compiled independently.

Fix those errors by including the needed header files or adding forward declarations. But be careful you don't end up with a cycle of includes, that's a bad idea and can usually be avoided with forward declarations.

stj
  • 9,037
  • 19
  • 33
john
  • 85,011
  • 4
  • 57
  • 81
  • Thank you! How did you know it was needed only in Weapon.h? – kidneyThief Aug 18 '18 at 07:37
  • 1
    @kidneyThief I didn't know it was **only** needed in Weapon.h but the error message `C:\Users\Name\CLionProjects\Call Of Matam Duties\Weapon.h:30:12: error: 'ostream' does not name a type friend ostream& operator<< (ostream& os, const Weapon& w);`` clearly indicates that's one place it is needed. – john Aug 18 '18 at 07:49
2

error: 'ostream' does not name a type

We can sort of infer here that the compiler thinks 'ostream' isn't defined. So you need to check that ostream is defined by including the iostream header file in Game.h (because ostream is defined in the iostream header file). If you're using ostream (or istream, cin, cout, etc) in the other header files, make sure that you put #include <iostream> in those files as well.

Also, line 2 (#include <iostream>) in main.cpp shouldn't be required if you have already included iostream in Game.h (correct me if I'm wrong).

Edit:

Since you seemed to be confused about how to trace this error... the compiler error tells you:

C:\Users\Name\CLionProjects\Call Of Matam Duties\Weapon.h:30:12:

This tells you that the error was found inside Weapon.h, line 30, 12 characters offset from the left.

TrebledJ
  • 8,713
  • 7
  • 26
  • 48
2

In addition to other answers it should be noted that there exists a special header <iosfwd> that can and should be used if only forward declarations from <iostream> are required. Typically, <iosfwd> is included in a header .h file, and <iostream> is included in the implementation .cpp file. More information can be found in this SO post.

Evg
  • 25,259
  • 5
  • 41
  • 83
  • Indeed. `` is an insanely expensive header to include. So when `` is all you need, *use* it. At least if you care about your build times. – Jesper Juhl Aug 18 '18 at 12:50