Page 1 of 1

base class undefined error. Please help!

Posted: Wed Jan 04, 2012 10:39 am
by Avishaiozeri
Hi everyone!

I'm working on my own little platformer type game (using c++ and sdl).

Currently, the engine i'v made can load a level from a file, and you can go around the level , there is collision detection, and a simple camera system, so all i need to add now are mobs, items, and a score system.

I'v started working on adding mobs to the game, and ran into a problem:

I have a 'level' class which loads the level data from a file. until now it only loaded the tiles and the 'borders' for the camera, Now i wanted it to load mobs aswell.

I've made a 'mob' class, which inherits a class called 'character' (which the 'player' class also inherits). The mobs work if you make them manually, so all i need to do is make a 'mobs' container in the 'level' class, so i can load into it mobs from the data file.

The problem is:
The 'character' class uses some functions in the 'level' class, so it includes "level.h"

Now the files look like this:

level.h:

Code: Select all

#ifndef LEVEL_H
#define LEVEL_H

#include "mob.h"

class Level
{
...
}

#endif
mob.h:

Code: Select all

#ifndef MOB_H
#define MOB_H

#include "character.h"

class mob : public character
{
...
}

#endif
character.h:

Code: Select all

#ifndef CHARACTER_H
#define CHARACTER_H

#include "level.h"

class character
{
...
}

#endif
It runs into a problem! the "level.h" in "character.h" is skipped, because "LEVEL_H" is already defined! that causes an error: " 'level' : undeclared identifier" when i use 'level' in the class 'character':
character.h:

Code: Select all

#ifndef CHARACTER_H
#define CHARACTER_H

#include "level.h" // Skipped because LEVEL_H is already defined!

class character
{
...
void someFunction (level *lvl); // Error!  'level' : undeclared identifier
..
}
#endif
I've solved it by declaring the 'level' class before i call the "mob.h":

level.h:

Code: Select all

#ifndef LEVEL_H
#define LEVEL_H

class level; //declare level class
#include "mob.h"

class level
{
...
}

#endif
Now 'character' knows 'level' is a class, so that issue is solved.

But now it gives me a new error:
"error C2504: 'Character' : base class undefined"

mob.h:

Code: Select all

#ifndef MOB_H
#define MOB_H

#include "character.h"

class mob : public character // Error! 'Character' : base class undefined!
{
...
}

#endif
I don't get it! why is 'character' not defined? It is defined! in: 'character.cpp'!

It only does this when i include "mob.h" in "level.h"

Why is this happening?? :(

Can someone please help? Thnx!

Re: base class undefined error. Please help!

Posted: Wed Jan 04, 2012 11:36 am
by Falco Girgis
Because you have extremely bad cyclic includes. Sit down and trace through this for a minute:

Starting with level.h
1) level.h includes mob.h
2) mob.h includes character.h
3) character.h includes level.h
4) repeat over and over until the compiler shits its pants.

You need to start using "forward declarations" rather than always including header files. A forward declaration can be used in a header when you are only referring to the class by pointer or reference. In lower-level speak, it's whenever the compiler doesn't need to know about the memory size of the class or its contents. Since you don't dereference it within a header file, there is no reason to include its header file. This also removes dependencies between header files and can drastically speed up your compilation time.

In character.h, change

Code: Select all

#include "level.h"
to

Code: Select all

class level;
And so-on for any other headers where you are only referencing that class/structure by pointer.

Note that you must include "character.h" in "mob.h," because you are inheriting from it. In this case, the compiler really does need all of the additional information in its header.

Re: base class undefined error. Please help!

Posted: Wed Jan 04, 2012 1:14 pm
by Avishaiozeri
Wow, I didn't know it was possible... How can a specific cpp file know what function/data a certain class holds without having the declaration of the class? And also, won't the #define LEVEL_H prevent the the include cycling?

I'v tried doing what you've said, and it gave me an error for every line i'v used the 'level' pointer in "character.cpp": "error C2027: use of undefined type 'level' " Did I do it wrong?

Thnx for the reply, and the awesome youtube channel! :bow:

Re: base class undefined error. Please help!

Posted: Wed Jan 04, 2012 2:12 pm
by Falco Girgis
Avishaiozeri wrote:Wow, I didn't know it was possible... How can a specific cpp file know what function/data a certain class holds without having the declaration of the class?
It can't. That's why you only forward declare in header files and only when you aren't dereferencing the structure.
Avishaiozeri wrote:And also, won't the #define LEVEL_H prevent the the include cycling?
Nope. That will ensure that the infinite loop of including stops (because nothing can be redefined), but follow the problem through like that:
Starting with level.h
1) level.h includes mob.h
2) mob.h includes character.h
3) character.h includes level.h
4) character.h CANNOT include level.h, because LEVEL_H is previously defined from its initial include.
Avishaiozeri wrote: I'v tried doing what you've said, and it gave me an error for every line i'v used the 'level' pointer in "character.cpp": "error C2027: use of undefined type 'level' " Did I do it wrong?
Yep, but you already know the reason. You only forwardly declare in your header file. You still include the header in your .cpp file.
Avishaiozeri wrote:Thnx for the replay, and the awesome youtube channel! :bow:
Thanks. We're working our asses off on Chapter 18. Hope you guys are ready. :D

Re: base class undefined error. Please help!

Posted: Wed Jan 04, 2012 2:38 pm
by Avishaiozeri
lol, I'm such an idiot.. I don't know why, but I always had this idea stuck to my head, that every cpp file should include only its own header, and any additional headers it needs should be included only in the header.. Never realized how stupid it is that every definition of a class needs to carry the definitions of the entire program on its back.. You've opened my eyes. Thnx. :)
Thanks. We're working our asses off on Chapter 18. Hope you guys are ready. :D
I'm checking my subscription box everyday!

Re: base class undefined error. Please help!

Posted: Wed Jan 04, 2012 2:44 pm
by Ginto8
It's actually possible to avoid cyclic include problems without having to include extra things when you include one. ie., if you just have a .h like this:

Code: Select all

#ifndef HEADER_H
#define HEADER_H
class Type;
//....
#endif
Then when including Header.h, you'd also have to include Type.h to provide the compiler with a definition for Type. Instead you can do this:

Code: Select all

#ifndef HEADER_H
#define HEADER_H
class Type;
//....
#include "Type.h"
#endif
This way, if you just include Header.h, it also includes the necessary Type.h, but if you include Header.h in Type.h, the #ifndef guards won't prevent Type from being declared for use by Header.h

Re: base class undefined error. Please help!

Posted: Wed Jan 04, 2012 2:48 pm
by Falco Girgis
^ This will work... nicely in the sense that it saves time and typing.

But you aren't removing the inter-header file dependency. That will eventually really slow down your build times.

Re: base class undefined error. Please help!

Posted: Wed Jan 04, 2012 2:56 pm
by Avishaiozeri
How about making two global header files: one that contains forward declaration for all classes, and one that contains the header files for all classes.
Then you could simply include the first header in every header file, and the second header in every cpp file.
Is it a waste to declare all classes in every cpp file, including those it doesn't use?

Re: base class undefined error. Please help!

Posted: Wed Jan 04, 2012 3:09 pm
by Falco Girgis
Avishaiozeri wrote:How about making two global header files: one that contains forward declaration for all classes, and one that contains the header files for all classes.
Then you could simply include the first header in every header file, and the second header in every cpp file.
Is it a waste to declare all classes in every cpp file, including those it doesn't use?
Jeeeeeeeeeeeeeeeeeeeeesus christ almighty.

I mean no offense, but you do realize what that would do for your dependencies? So now every .cpp file is dependent upon EVERY header file in your project? Your build times will be complete shit.

Re: base class undefined error. Please help!

Posted: Wed Jan 04, 2012 3:18 pm
by Avishaiozeri
Well, so far my projects have been quite small, so I didn't know build times were an issue, lol.

Re: base class undefined error. Please help!

Posted: Wed Jan 04, 2012 6:49 pm
by Falco Girgis
Avishaiozeri wrote:Well, so far my projects have been quite small, so I didn't know build times were an issue, lol.
For small projects? No. But it's still a good habit to get into. Good coding practices are good coding practices.

Our engine takes about 2-3 minutes from scratch.

Our Toolkit takes about 5-10 minutes from scratch.

I work for a company whose software easily takes half an hour from scratch on an i7... yeah, it's kind of a big deal.

Re: base class undefined error. Please help!

Posted: Thu Jan 05, 2012 7:31 am
by Avishaiozeri
Holy shit! Debugging must be a nightmare!

Re: base class undefined error. Please help!

Posted: Thu Jan 05, 2012 10:54 pm
by dandymcgee
Avishaiozeri wrote:Holy shit! Debugging must be a nightmare!
The compiler doesn't rebuild the entire project every time you change one file.. that would be horrific. :|

Re: base class undefined error. Please help!

Posted: Fri Jan 06, 2012 7:13 am
by Falco Girgis
dandymcgee wrote:
Avishaiozeri wrote:Holy shit! Debugging must be a nightmare!
The compiler doesn't rebuild the entire project every time you change one file.. that would be horrific. :|
It pretty much will if you use his inclusion scheme. ;)

Re: base class undefined error. Please help!

Posted: Fri Jan 06, 2012 12:51 pm
by dandymcgee
GyroVorbis wrote:
dandymcgee wrote: The compiler doesn't rebuild the entire project every time you change one file.. that would be horrific. :|
It pretty much will if you use his inclusion scheme. ;)
Very true. :lol: