problem with recursive includes, and forward declaration

Hi OF.

I’m currently having a problem with recursive includes.
I have a class Creature and the classes Eyes, Ears and Mouth.
Class Creature includes the classes Eyes, Ears, and Mouth. I would also to create a pointer inside the Eyes, Ears and Mouth classes to the class creature.
I’m using forward declaration to declare the Creature class, but whenever i try to access any information from that pointer, i get two errors

“error: invalid use of undefined type ‘struct Creature’” and
“error: forward declaration of ‘struct Creature’”

here’s my include codes:

#ifndef CREATURE_H  
#define CREATURE_H  
#include "Ears.h"  
#include "Eyes.h"  
#include "Mouth.h"  
class Creature{  
//some vars...  
Ears ears;  
Eyes eyes;  
Mouth mouth;  
//some other functions...  


#ifndef EYES_H  
#define EYES_H  
#include "ofMain.h"  
#include "ofAddons.h"  
class Creature;  
class Eyes{  
	Creature *creaturePtr;  
	//some vars...  
	Eyes(Criatura * _mae);  
	void move();  
	void render();  

and the Eyes.cpp i’m trying to do this in the render function

ofPoint center = creaturePtr->center;  
//some other stuff...  

and that is where i get the errors…

the other classes look pretty much like this one. if i dont try to access anything from that pointer creaturePtr it compiles and runs fine…

Could any one give some help???
i dont understand why this error occurs…


hey pelintra,

do you have a #include “creature.h” in your Eyes.cpp file?
Let me know if that helps.

Hi fiezi.

Yes!! it works now :slight_smile:

but i dont understand how that works, because before i had a #include “Creature.h” in my Eyes.h file and that wouldn’t even compile. would you care to elaborate a little as to why it works now??

thanks a lot


hey pelintra,

unfortunately i do not have a very solid understanding of the way that linking works in C++.
Maybe someone that lives C++ can jump in and explain this to all of us?

I think it has something to do with not creating loops in the #include definitions.
An #include basically takes the contents of the file you want to include and pastes it right in (that’s why #ifdef’s become important at some point).

Now, when two .h files reference each other, that would create an infinite loop of copy and paste.
The fact that .cpp files do not reference other .cpp files and .h files don’t reference .cpp files either allows the inclusion of any .h file in a .cpp file (does that make sense?) because it does not create a loop!

That’s why, for every forward declaration, you might want to include the corresponding .h file in your .cpp file in order to break out of the looping pattern.

I’ll try an example:

let's say wheel.h includes car.h . That means:  
wheel.cpp includes wheel.h -> means that it also includes car.h  
now if car.h includes wheel.h too, you have a loop like this:  
wheel.cpp includes wheel.h -> which in turn includes car.h -> also includes wheel.h -> also includes car.h -> etc... loops to infinity  
whereas if wheel.h has forward declaration of class car (but does not paste the .h file!)   
and you include car.h in your wheel.cpp file , you have the following:  
wheel.cpp includes car.h -> includes wheel.h -> forward declaration of class car -> that's it!  

Does that make any sense? The compiler goes from .cpp to .h file, so if you do a forward declaration, the actual .h file gets pasted in the .cpp file before the forward declaration and thus the compiler knows what you’re talking about!

I personally belief that the reason people invented computers is for us to not deal with stuff like this anymore… but for now there’s no way around it.
Hope this made sense.

it kinda made sense… i think i understand why including in the .cpp file works, but i still dont quite understand why the forward declaration didn’t work. because doing the
#ifndef SOMENAME … #endif trick will mean that no file will be included more than once, so it shouldn’t loop infinitely. so yeah… maybe someone who understands this could jump in and explain it *hint*;)*hint*

anyway i’ll remember that as a rule for the next time i get similar errors and for now everything is working fine so thanks :slight_smile: