Page 1 of 1

Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 2:03 pm
by JS Lemming
Welp, fell on my face. This one is kinda hard to explain.

I have stage class and I have various stage object classes (like hector and pipes). I need to pass an instance of stage to these stage objects but it requires that stage.h be included in these stage objects header files BUT stage.h needs to include these stage object headers in order to declare lists of them.

stage.h

Code: Select all

#include "gyroPipe.h"

using namespace std;

class stage
{
	public:
		list<gyroPipe*> gyroPipes;
		list<gyroPipe*>::iterator iGyroPipes;
...
gyroPipe.h

Code: Select all

#include "stage.h"

class gyroPipe
{
	public:
		gyroPipe(stage *stageInstance, int argColor, bool argVertical, int argX, int argY, int argLength);
...
I thought maybe extern could help me out here but I'm not sure how that would work.

Re: Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 2:18 pm
by MarauderIIC
Define a class prototype.

IE:

gyropipe.h

Code: Select all

#ifndef GYROPIPE_H //Standard include guards
#define GYROPIPE_H

//Only #include stage.h if you really need to
class Stage; //class prototype

class GyroPipe {
 GyroPipe(Stage* stageInstance...)
};
#endif
stage.h

Code: Select all

#ifndef STAGE_H
#define STAGE_H

//Only #include "gyropipe.h" if you really need to
class GyroPipe; //class prototype

class Stage {
 ....
};
#endif
Also, in C++, classes usually start with capital letters, as above. That way you can do Stage* stage, for instance

Re: Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 2:22 pm
by Ginto8
From your post, can't see anything wrong, except add a few things to prevent ambiguity:

at the beginning of the header files, put:

Code: Select all

#ifndef [filename]_H
#define [filename]_H
where [filename] is the filename without ".h" (in caps). This makes sure that the content only appears once.

At the end of the files, put:

Code: Select all

#endif
Lazyfoo does a better job at explaining it, here.

Re: Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 2:23 pm
by MarauderIIC
We must've posted at the same time :) Include guards prevent a file from being pasted into your project more than once by the compiler (causing compilation errors)

Re: Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 2:33 pm
by Ginto8
#defines have 2 purposes: creating constants and preventing ambiguity. You have now learned one of them. :) From two people at once.

Re: Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 2:34 pm
by MarauderIIC
C++ prefers const for the "creating constants," though =)

Re: Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 2:48 pm
by Ginto8
That's true, but there's no saying you can't use #define... I wasn't saying #define was the only way to do so, or even the best. It's just that those are really the only two reasons to use them these days, seeing as macros aren't as good as inline functions

Re: Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 3:54 pm
by JS Lemming
Thanks Mar, that's exactly what I needed.

FYI, my real code does have the guards. I just didn't post them so as to direct focus on the problem. I realize that was retarded of me.

Re: Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 4:03 pm
by MarauderIIC
Haha, np. With any luck someone that doesn't know about include guards will come across the post :)

Re: Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 4:22 pm
by Ginto8
Well, if you have the guards, there shouldn't be any problem. You might not understand how the compiler manages to make it work, but the compiler does. ;)

Re: Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 4:27 pm
by JS Lemming
Ginto8 wrote:Well, if you have the guards, there shouldn't be any problem. You might not understand how the compiler manages to make it work, but the compiler does. ;)
.... no. It doesn't. The way I had it didn't work. The files relied on each other in an impossible kind of way. Class prototyping fixed that.

Re: Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 5:57 pm
by Falco Girgis
Yeah, his problem wasn't that his classes were being redefined. They weren't being defined.

Re: Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 6:08 pm
by MarauderIIC
The pattern

Class A { B b};
Class B { A a};

is what you need a class prototype to solve. This was his issue.

Re: Header files, one can't work without the other & vice versa

Posted: Mon Jan 19, 2009 6:59 pm
by Ginto8
:oops: Okay... yeah this is one of the reasons why I'm still in the learning process. :mrgreen: I'm glad that I was wrong, actually. I learned something here. ;)