473,480 Members | 1,897 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Problem with #includes, friend classes, and forward declarations.

boxfish
469 Recognized Expert Contributor
Hi everyone, I'm working on a 3d maze game, and I just messed up the classes so it won't compile, and I need help sorting it out. There's a class Maze, whose members are, among other things, a list of the walls, the user who is an object of class MazePerson, and a yellow square who is an object of class MazeMonster. MazePerson and MazeMonster are both inherited from class MazeThing, which takes care of stuff like collisions. MazePerson, MazeMonster, and MazeThing used to be structs inside of class Maze like this:

Maze.h:
Expand|Select|Wrap|Line Numbers
  1. #ifndef MAZE_H
  2. #define MAZE_H
  3. ...
  4. using namespace std;
  5.  
  6. class Maze {
  7. public:
  8.     ...
  9. private:
  10.     ...
  11.     struct MazeThing {
  12.         ...
  13.     };
  14.     struct MazePerson : public MazeThing {
  15.         ...
  16.     };
  17.     struct MazeMonster : public MazeThing {
  18.         ...
  19.     };
  20.     ...
  21.     MazePerson person;
  22.     MazeMonster monster;
  23.     ...
  24. };
  25.  
  26. #endif
  27.  
Now I want to take MazeThing, MazePerson, and MazeMonster out of class Maze, give each of them their own header file, let them be real classes, make Maze be a friend of all of them, and make all of them friends of class Maze. Here's what I did:

Maze.h:
Expand|Select|Wrap|Line Numbers
  1. #ifndef MAZE_H
  2. #define MAZE_H
  3. ...
  4. #include "MazePerson.h"
  5. #include "MazeMonster.h"
  6.  
  7. using namespace std;
  8.  
  9. class Maze {
  10. public:
  11.     friend class MazeThing;
  12.     ...
  13. private:
  14.     ...
  15.     MazePerson person;
  16.     MazeMonster monster;
  17.     ...
  18. };
  19.  
  20. #endif
  21.  
MazeThing.h:
Expand|Select|Wrap|Line Numbers
  1. #ifndef MAZETHING_H
  2. #define MAZETHING_H
  3.  
  4. class Maze;
  5.  
  6. class MazeThing {
  7. public:
  8.     friend class Maze;
  9. protected:
  10.     ...
  11.     Maze *myMaze;
  12.     ...
  13. };
  14.  
  15. #endif
  16.  
MazePerson.h
Expand|Select|Wrap|Line Numbers
  1. #ifndef MAZEPERSON_H
  2. #define MAZEPERSON_H
  3.  
  4. #include "MazeThing.h"
  5.  
  6. class Maze;
  7.  
  8. class MazePerson : public MazeThing {
  9. public:
  10.     friend class Maze;
  11.     ...
  12. };
  13.  
  14. #endif
  15.  
MazeMonster.h
Expand|Select|Wrap|Line Numbers
  1. #ifndef MAZEMONSTER_H
  2. #define MAZEMONSTER_H
  3.  
  4. #include "MazeThing.h"
  5.  
  6. class Maze;
  7.  
  8. class MazeMonster : public MazeThing {
  9. public:
  10.     friend class Maze;
  11.     ...
  12. };
  13.  
  14. #endif
  15.  
But wherever I use MazeThing's member myMaze in MazeThing.cpp I get these errors:

invalid use of undefined type `struct Maze'
forward declaration of `struct Maze'

I've tried changing around the #includes and forward declarations, but I always get errors. Any help would be greatly appreciated.
Jul 12 '08 #1
8 3707
weaknessforcats
9,208 Recognized Expert Moderator Expert
This compiles:
Expand|Select|Wrap|Line Numbers
  1. class MazeThing {
  2.         //...
  3.     };
  4. struct MazePerson : public MazeThing {
  5.         //...
  6.     };
  7. struct MazeMonster : public MazeThing {
  8.         //...
  9.     };
  10.  
  11.  
  12. #ifndef MAZE_H
  13. #define MAZE_H
  14. //...
  15. //#include "MazePerson.h"
  16. //#include "MazeMonster.h"
  17.  
  18. using namespace std;
  19.  
  20. class Maze {
  21. public:
  22.     friend class MazeThing;
  23.     //...
  24. private:
  25.     //...
  26.     MazePerson person;
  27.     MazeMonster monster;
  28.     //...
  29. };
  30. #endif
  31.  
Basically, all I did was change your struct MazeThing to class MazeThing. I did that because you declared friend class rather than friend struct.
Jul 13 '08 #2
boxfish
469 Recognized Expert Contributor
Thanks so much for your reply! But MazeThing already was a class. But when I put everything in one file like you did, it works! So it seems like I have to figure out how to get the #includes right so the classes end up in that order after the preprocessor does its thing. Oh wait, maybe it's because I didn't use namespace std on all of them...
Okay I didn't, let me try that...
Thanks again!
Jul 13 '08 #3
boxfish
469 Recognized Expert Contributor
Okay, that didn't work. There's another error I can get instead if, instead of a forward declaration of class Maze in MazeThing.h, I #include "Maze.h".
It goes like this:

In file included from Maze.h
from MazeThing.h
from MazeThing.cpp
parse error before `{' token
parse error before `}' token
In file included from Maze.h
from MazeThing.h
from MazeThing.cpp
parse error before `{' token
parse error before `}' token
In file included from MazeThing.h
from MazeThing.cpp
field `person' has incomplete type
field `monster' has incomplete type

When it says `{' and `}' tokens, It points to the opening and closing braces of a class:
Expand|Select|Wrap|Line Numbers
  1. #ifndef MAZEMONSTER_H
  2. #define MAZEMONSTER_H
  3.  
  4. #include "MazeThing.h"
  5.  
  6. using namespace std;
  7.  
  8. class Maze;
  9.  
  10. class MazeMonster : public MazeThing { // << This one
  11. public:
  12.     friend class Maze;
  13.     ...
  14. }; // << and this one..
  15.  
  16. #endif
  17.  
It does this in MazePerson.h and MazeMonster.h.

When It says field monster and field person, it points to the MazePerson person and MazeMonster monster members of class Maze.

Does anyone have any ideas?

I'm using Dev-C++ 4.9.8.0 on Windows XP, if that helps.

Thanks for any help you can give me.
Jul 13 '08 #4
mkborregaard
20 New Member
How does your MazeThing constructor look?
Jul 15 '08 #5
weaknessforcats
9,208 Recognized Expert Moderator Expert
class MazeMonster : public MazeThing { // << This one
When you compiler says parse error before {, it is trying tell you that when the { was encountered it was unexpected. Therefore, the parse knows there is trouble either with the { or the code preceding it. Like maybe MazeThing.

Keep in mind that you are using templates. The compiler requires the templates to precede any use of the templates. You either a) put all the templates together in the correct order in one header file and include it or b) use multiple header files that are included in the correct order.

You cannot have some of your templates in other files because templates are not code. They are patterns the compiler copies, substitutes a real type for the template type and this becomes the real code.
Jul 15 '08 #6
boxfish
469 Recognized Expert Contributor
Hi, Thanks for your replies. My problem magically went away just now. I put everything into one file, and that made it work, and I just put it back into separate files and it still works. I thought that maybe not everything had been recompiled, so I clicked rebuild all, and it still worked. Ok, I just found out what I changed that made it work: MazePerson.cpp and MazeMonster.cpp now both include Maze.h instead of their own header files. It seems weird to me that that made it work, but I guess If they include their own header files, stuff ends up in the wrong order, and by including Maze.h, they indirectly include their own header files, because Maze.h includes them.
@mkborregaard: MazeThing currently does not have a constructor. Maze initializes its MazeThing objects' variables in its own constructor. That is not good and I need to fix it.
@weaknessforcats: I don't know what you mean by templates. I thought templates were functions and classes that could be instantiated to work with new variable types as needed. I didn't think I was using them. Does it have to do with inheritance? Eventually I want to go through all the files, figure out (by trial and error) which includes are unnessecary (I have such a hard time spelling that), and get rid of them. They seem like a mess right now.
Thanks again.
Jul 15 '08 #7
mkborregaard
20 New Member
@mkborregaard: MazeThing currently does not have a constructor. Maze initializes its MazeThing objects' variables in its own constructor. That is not good and I need to fix it.
OK. I was just wondering whether your problem was related to the uninitialized Maze* pointer (which i guess you intend to initialize in the MazeThing constructor to point to the Maze object owning MazeThing). Cool you got it solved, though.
Jul 16 '08 #8
boxfish
469 Recognized Expert Contributor
OK. I was just wondering whether your problem was related to the uninitialized Maze* pointer (which i guess you intend to initialize in the MazeThing constructor to point to the Maze object owning MazeThing). Cool you got it solved, though.
Yeah. But if it was a problem with an uninitialized pointer, I probably would have gotten an access violation, not a compiler error. I'm going to go try to make it a multi-story maze with ramps leading between the levels now.
Jul 16 '08 #9

Sign in to post your reply or Sign up for a free account.

Similar topics

5
8424
by: Yoon-Soo Lee | last post by:
I am using Visual C++ .NET 2003 and running into some linking error from the following template code. The error messages is error LNK2019: unresolved external symbol "class...
10
2082
by: Chris Gordon-Smith | last post by:
I am currently revisiting the code of a C++ application and restructuring the code where appropriate to make it consistent with the overall logical design. As part of this, I am looking at the...
5
1439
by: James Aguilar | last post by:
Hello, all. I saw this in the provided code of a lab that I have due in a couple of weeks in my algorithms class. It compiled fine in g++ but did not compile with the VC++ compiler. It does...
7
1192
by: mpaliath | last post by:
Suppose I have 2 classes X & Y declared in X.h & Y.h and defined in X.cpp & Y.cpp. If I have a function which returns an object of X in Y and one which returns an object of X in Y how where and in...
4
8174
by: ckpun1978 | last post by:
Hi, I am now designing a program related to "graph". In particular, I would like to have 2 objects. #1. node #2. branch
10
1332
by: Ben Taylor | last post by:
Hi, Coming from VB, I've still not really grasped the way how in C++ if function A wants to call function B, then function B has to be before function A in the compilation, and #includes that use...
9
5481
by: silversurfer2025 | last post by:
Hello everyone, I am currently having problems with a C++ abstract class. I have a class FrameWork.h which defines some methods (of which some are abstract, i.e. virtual void method() = 0). In...
5
1808
by: Steven T. Hatton | last post by:
This note appears in the discussion of name hiding and uniqueness: §3.3 #4 This note is item #6 in the discussion of "Point of declaration" §3.3.1 #6 What exactly do these statements mean?...
6
1719
by: ralphmerridew | last post by:
My current project involves reading a particular data format. It would be convenient to be able to do something like: class DataClass { friend bool FileRunner::read_data (const...
0
7041
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
6908
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7043
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
6737
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
1
4776
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4481
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
2984
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1300
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
563
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.