473,890 Members | 1,658 Online
Bytes | Software Development & Data Engineering Community
+ 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 3740
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.
@weaknessforcat s: 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
8467
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 std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Test<int> &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$Test@H@@@Z ) referenced in function _main
10
2118
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 way .cpp files #include headers. My question is this: Is there a standard order in which heders should be included? I tend to #include STL headers first, and my own headers later, but I can't really think of a logical justification for this.
5
1458
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 not recognize the angle brackets that follow "<<" in the operator friend declaration. --- CODE --- template <class T> class PriorityQueue {
7
1210
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 what order do I include the files X,Y.cpp,.h Also sometimes while working in Visual C++, after adding some code manually I find that some classes dissapear from the class view tab. If I try to add the class again with the already existing files...
4
8193
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
1366
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 the classes in others rely on others have to be after them accordingly. I've got three questions about this if I may, 1) When I create an MFC application by having a dialog
9
5514
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 FrameWork.cpp I define some of the methods while I naturally leave the abstract methods undefined. Now I wrote a class FrameWork_GUI.h which inherits from the abstract FrameWork class and implements the missing (so far abstract) methods....
5
1829
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? "laborated-type-specifiers and friend declarations may introduce a
6
1733
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 vector<string>&); ... }; class OtherDataClass {
0
9977
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10802
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9618
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
8009
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
7161
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5837
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
6036
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
4260
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3268
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.