Skip to main content
GameDev.net gamedev.net
🔒 Locked

question about headers

Started by Marty666 Feb 1, 2004 at 9:26 AM 20 replies 2k views
Original Post
Marty666
Marty666
Hi all, I have a question about headers. I used to use one header file with all the definitions. I''m trying to make my program more neatly now, so i want to give each .cpp file it''s own header. I''ve had a problem with cross including (header one is using stuff declared in header two and the other way around). So chicken and egg problem. I tried to solve this using #ifndef _HEADER_ #define _HEADER .... #endif This seems not to work either. What should I do? Thanx, Marty
_ /__ /|| | || MtY | ||_____|/Marty
evolutional
evolutional
Easy.



class A {
B *m_b;

}

class B{
A *m_a;
}



In A.h...

class B; >--- note WITHOUT the implementation

class A
{ ..... etc

In B.h...

class A;

class B
{ ...... etc



You declare your use of the class without actually defining it.
Marty666
Marty666
So this should work?


// header 1:

#ifndef _HEAD1_
#define _HEAD1_
#include "header2"

class A
{
B Convert_A_to_B();
};

#endif



// header 2:

#ifndef _HEAD2_
#define _HEAD2_
#include "header1"

class B
{
A Convert_B_to_A();
};

#endif


_ /__ /|| | || MtY | ||_____|/Marty
Marty666
Marty666
I still get these errors. Can anyone explain what I''m doing wrong? Thanx!

Marty

--------------------Configuration: NukeM2 - Win32 Debug--------------------
Compiling...
model.cpp
c:\program files\microsoft visual studio\vc98\include\gl\gl.h(1152) : error C2144: syntax error : missing '';'' before type ''void''
c:\program files\microsoft visual studio\vc98\include\gl\gl.h(1152) : error C2501: ''WINGDIAPI'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\vc98\include\gl\gl.h(1152) : fatal error C1004: unexpected end of file found
textures.cpp
c:\program files\microsoft visual studio\vc98\include\gl\gl.h(1152) : error C2144: syntax error : missing '';'' before type ''void''
c:\program files\microsoft visual studio\vc98\include\gl\gl.h(1152) : error C2501: ''WINGDIAPI'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\vc98\include\gl\gl.h(1152) : fatal error C1004: unexpected end of file found
frustum.cpp
c:\program files\microsoft visual studio\vc98\include\gl\gl.h(1152) : error C2144: syntax error : missing '';'' before type ''void''
c:\program files\microsoft visual studio\vc98\include\gl\gl.h(1152) : error C2501: ''WINGDIAPI'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\vc98\include\gl\gl.h(1152) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

NukeM2.exe - 9 error(s), 0 warning(s)
_ /__ /|| | || MtY | ||_____|/Marty
EL
EL
As downgraded said:


// header 1:

#ifndef _HEAD1_
#define _HEAD1_

class B;

class A
{
B Convert_A_to_B();
};

#endif



// header 2:

#ifndef _HEAD2_
#define _HEAD2_

class A;

class B
{
A Convert_B_to_A();
};

#endif


edit: I think those errors can be resolved by including windows.h before all other headers.

[edited by - EL on February 1, 2004 10:42:08 AM]
evolutional
evolutional
More like



#include "b.h"

class B;

class A
{
B *m_somepointertoB;

};





#include "a.h"

class A;

class B
{
A *m_somepointertoA;

};

Marty666
Marty666
Ok, I get it now. Quity simple Thank you guys!
I used the gl.h more, but i never included windows.h, strange. I''ll try it anyways.

Thanx a lot ppl :D

Marty
_ /__ /|| | || MtY | ||_____|/Marty
Marty666
Marty666
Ok, the including of windows helps

One more question.
Is is bad to have more headers that #include <windows.h> or . So whould i only include them once, or is it ok because the compiler takes care of it?

TY,
Marty
_ /__ /|| | || MtY | ||_____|/Marty
Marty666
Marty666
Ok, i made a header file with all the predefinitions. All other headers include this file first, so they''ll know all classes. What happenes is that in the .cpp files the classes don''t have their functions, like they we''re not redefined.

this is the predef.h file:

#pragma once

class c_entity;
class c_matrix;
class c_model;
class c_quat;
class c_vec3;


the other header files first include this one and then they include the header with the complete definition of the class.

Still in the .cpp files it''s like the class was never defined completely. I get errors like this:

C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(118) : error C2027: use of undefined type ''c_vec3''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\predef.h(7) : see declaration of ''c_vec3''
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(118) : error C2228: left of ''.X'' must have class/struct/union type
_ /__ /|| | || MtY | ||_____|/Marty
Marty666
Marty666
And still model.cpp includes model.h and model.h first includes predef.h and then vector.h.
_ /__ /|| | || MtY | ||_____|/Marty
evolutional
evolutional
You still need to include the headers in your ''all catch'' header
Marty666
Marty666
I really wanted not to catch all in one header, because it might as well be one big header. To keep certain parts of the program exchangeable with other programs i wanted to give them their own headers with all they need in it. Some of the headers point to other though, because the functions declared are related to functions in the other header. The problem is that I can''t seem to predefine a class...

when i type this in a header

class A;
class B
{
A some_function_that_returns_A();
};

it''s ok, but in the .cpp file i get the errors shown like before.

argh, getting sick of this. Have been busy all day trying to get this to work.

I tried to #include each and every header in de predef.h file (ofcourse after the predefinitions) but i still get these same errors

Marty
_ /__ /|| | || MtY | ||_____|/Marty
evolutional
evolutional
For each header that uses another one, include it.

If the definition of an included class requires the use of another then predefine the original class in there.

I had this header spaghetti once. I tore out all my includes and started again.
Marty666
Marty666
Ok, this is my ''predef.h'' file, or catch-all as you call it.


#pragma once

class c_entity;
class c_matrix;
class c_model;
class c_quat;
class c_vec3;

#include "camera.h"
#include "entity.h"
#include "frustum.h"
#include "matrix.h"
#include "model.h"
#include "physics.h"
#include "quaternion.h"
#include "sound.h"
#include "textures.h"
#include "vector.h"

#include <math.h>
#include <windows.h> // before gl\gl.h

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include <vector>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>


all headers only include this file.

these are the errors i get:
(there might be some errors that aren''t relevant but stuff i didn''t debug yet)

Compiling...
frustum.cpp
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(27) : error C2079: ''Model'' uses undefined class ''c_model''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(28) : error C2079: ''Orientation'' uses undefined class ''c_quat''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(35) : error C2061: syntax error : identifier ''GLuint''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2146: syntax error : missing '';'' before identifier ''Texture''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2501: ''GLuint'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2501: ''Texture'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\textures.h(12) : error C2061: syntax error : identifier ''GLuint''
matrix.cpp
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(27) : error C2079: ''Model'' uses undefined class ''c_model''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(28) : error C2079: ''Orientation'' uses undefined class ''c_quat''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(35) : error C2061: syntax error : identifier ''GLuint''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2146: syntax error : missing '';'' before identifier ''Texture''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2501: ''GLuint'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2501: ''Texture'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\textures.h(12) : error C2061: syntax error : identifier ''GLuint''
model.cpp
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(27) : error C2079: ''Model'' uses undefined class ''c_model''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(28) : error C2079: ''Orientation'' uses undefined class ''c_quat''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(35) : error C2061: syntax error : identifier ''GLuint''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2146: syntax error : missing '';'' before identifier ''Texture''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2501: ''GLuint'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2501: ''Texture'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\textures.h(12) : error C2061: syntax error : identifier ''GLuint''
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(3) : error C2653: ''std'' : is not a class or namespace name
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(3) : error C2143: syntax error : missing '';'' before ''<''
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(3) : error C2501: ''vector'' : missing storage-class or type specifiers
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(3) : error C2143: syntax error : missing '';'' before ''<''
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(37) : warning C4018: ''<'' : signed/unsigned mismatch
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(39) : warning C4018: ''<'' : signed/unsigned mismatch
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(58) : warning C4018: ''<'' : signed/unsigned mismatch
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(101) : error C2143: syntax error : missing '';'' before ''>=''
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(101) : error C2059: syntax error : '')''
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(102) : error C2143: syntax error : missing '';'' before ''{''
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(108) : error C2181: illegal else without matching if
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(155) : error C2065: ''TempObjects'' : undeclared identifier
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(155) : error C2228: left of ''.clear'' must have class/struct/union type
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(168) : error C2228: left of ''.size'' must have class/struct/union type
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(169) : error C2228: left of ''.push_back'' must have class/struct/union type
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(251) : error C2228: left of ''.size'' must have class/struct/union type
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(252) : error C2228: left of ''.size'' must have class/struct/union type
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(253) : error C2228: left of ''.size'' must have class/struct/union type
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(255) : error C2109: subscript requires array or pointer type
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(255) : error C2679: binary ''='' : no operator defined which takes a right-hand operand of type ''int'' (or there is no acceptable conversion)
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(257) : error C2664: ''FindEdges'' : cannot convert parameter 1 from ''class c_model *const '' to ''class c_model &''
A reference that is not to ''const'' cannot be bound to a non-lvalue
quaternion.cpp
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(27) : error C2079: ''Model'' uses undefined class ''c_model''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(28) : error C2079: ''Orientation'' uses undefined class ''c_quat''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(35) : error C2061: syntax error : identifier ''GLuint''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2146: syntax error : missing '';'' before identifier ''Texture''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2501: ''GLuint'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2501: ''Texture'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\textures.h(12) : error C2061: syntax error : identifier ''GLuint''
textures.cpp
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(27) : error C2079: ''Model'' uses undefined class ''c_model''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(28) : error C2079: ''Orientation'' uses undefined class ''c_quat''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(35) : error C2061: syntax error : identifier ''GLuint''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2146: syntax error : missing '';'' before identifier ''Texture''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2501: ''GLuint'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2501: ''Texture'' : missing storage-class or type specifiers
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\textures.cpp(22) : error C2664: ''glGenTextures'' : cannot convert parameter 2 from ''unsigned int'' to ''unsigned int *''
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
vector.cpp
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(16) : error C2079: ''Pos'' uses undefined class ''c_vec3''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(17) : error C2079: ''Vel'' uses undefined class ''c_vec3''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(18) : error C2079: ''Acc'' uses undefined class ''c_vec3''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(27) : error C2079: ''Model'' uses undefined class ''c_model''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(28) : error C2079: ''Orientation'' uses undefined class ''c_quat''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(35) : error C2061: syntax error : identifier ''GLuint''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2146: syntax error : missing '';'' before identifier ''Texture''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2501: ''GLuint'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\entity.h(38) : error C2501: ''Texture'' : missing storage-class or type specifiers
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\model.h(23) : error C2079: ''Normal'' uses undefined class ''c_vec3''
c:\program files\microsoft visual studio\myprojects\objloader\nukem2\textures.h(12) : error C2061: syntax error : identifier ''GLuint''
Error executing cl.exe.

NukeM2.exe - 64 error(s), 3 warning(s)

_ /__ /|| | || MtY | ||_____|/Marty
Enigma
Enigma
WARNING - very long post ahead. If you don't want to read it, skip to the 'moral of the story' at the end of the post. Sorry for the story-like format - it was just more fun to write that way!

Say you have two classes:
class First
{
public:
First()
{
memberVariable2 = 0;
}
void add(Second s)
{
memberVariable1.add(s);
}
void add(First f)
{
memberVariable2 += f.memberVariable2;
}
private:
Second memberVariable1;
int memberVariable2;
};

and
class Second
{
public:
Second()
{
memberVariable2 = 0;
}
void add(First f)
{
memberVariable1.add(f);
}
void add(Second s)
{
memberVariable2 += s.memberVariable2;
}
private:
First memberVariable1;
int memberVariable2;
};

And you want to do:
int main()
{
First f;
Second s;
f.add(s);
s.add(f);
}


So you put First into First.h and Second into Second.h and add #include "First.h" and #include "Second.h" to the top of your main cpp file.

Now you compile but get (borland 5.6.4):
Error E2293 First.h 8: ) expected
Error E2316 Second.h 10: 'add' is not a member of 'First' in function Second::add(First)
Error E2316 tmp.cpp 8: 'add' is not a member of 'First' in function main()


So you look at line 8 of First.h and find:
void add(Second s) 

'Ah!' You think, at this point the compiler doesn't know about Second, so I'll just add #include "Second.h" to the top of First.h, recompile and hopefully all the errors will go away*.

So you do that and compile but get:
Error E2293 Second.h 8: ) expected
Error E2316 First.h 12: 'add' is not a member of 'Second' in function First::add(Second)
Error E2238 Second.h 2: Multiple declaration for 'Second'
Error E2344 Second.h 1: Earlier declaration of 'Second'
Error E2316 tmp.cpp 9: 'add' is not a member of 'Second' in function main()


So you look at line 8 of Second.h and find:
void add(First f) 

'Ah!' You think, at this point the compiler doesn't know about First, so I'll just add #include "First.h" to the top of Second.h, recompile and hopefully all the errors will go away*².

So you do that and compile but get:
Fatal F1005 First.h 1: Include files nested too deep 


'Oops!' you think, I need to put inclusion guards round both header files to stop infinite inclusion recursion.

So you do that and compile but get:
Error E2293 Second.h 12: ) expected
Error E2316 First.h 14: 'add' is not a member of 'Second' in function First::add(Second)
Error E2316 tmp.cpp 9: 'add' is not a member of 'Second' in function main()


So you look at line 12 of Second.h and find:
void add(First f)   

Huh?!?! you think, scratching your head (for you are somewhat confused). I thought I'd solved that problem. What's going wrong?

So you run your code through the preprocessor and find that you get:
/* tmp.cpp 1: */

/* First.h 1: */

/* First.h 2: */
/* First.h 3: */

/* Second.h 1: */

/* Second.h 2: */
/* Second.h 3: */

/* First.h 1: */

/* First.h 2: */
/* First.h 3: */
/* First.h 4: */
/* First.h 5: */
/* First.h 6: */
/* First.h 7: */
/* First.h 8: */
/* First.h 9: */
/* First.h 10: */
/* First.h 11: */
/* First.h 12: */
/* First.h 13: */
/* First.h 14: */
/* First.h 15: */
/* First.h 16: */
/* First.h 17: */
/* First.h 18: */
/* First.h 19: */
/* First.h 20: */
/* First.h 21: */
/* First.h 22: */
/* First.h 23: */
/* First.h 24: */
/* First.h 25: */
/* First.h 26: */
/* First.h 27: */
/* Second.h 4: */
/* Second.h 5: */class Second
/* Second.h 6: */{
/* Second.h 7: */public:
/* Second.h 8: */Second()
/* Second.h 9: */{
/* Second.h 10: */memberVariable2 = 0;
/* Second.h 11: */}
/* Second.h 12: */void add(First f)
/* Second.h 13: */{
/* Second.h 14: */memberVariable1.add(f);
/* Second.h 15: */}
/* Second.h 16: */void add(Second s)
/* Second.h 17: */{
/* Second.h 18: */memberVariable2 += s.memberVariable2;
/* Second.h 19: */}
/* Second.h 20: */private:
/* Second.h 21: */First memberVariable1;
/* Second.h 22: */int memberVariable2;
/* Second.h 23: */};
/* Second.h 24: */
/* Second.h 25: */
/* Second.h 26: */
/* Second.h 27: */
/* First.h 4: */
/* First.h 5: */class First
/* First.h 6: */{
/* First.h 7: */public:
/* First.h 8: */First()
/* First.h 9: */{
/* First.h 10: */memberVariable2 = 0;
/* First.h 11: */}
/* First.h 12: */void add(Second s)
/* First.h 13: */{
/* First.h 14: */memberVariable1.add(s);
/* First.h 15: */}
/* First.h 16: */void add(First f)
/* First.h 17: */{
/* First.h 18: */memberVariable2 += f.memberVariable2;
/* First.h 19: */}
/* First.h 20: */private:
/* First.h 21: */Second memberVariable1;
/* First.h 22: */int memberVariable2;
/* First.h 23: */};
/* First.h 24: */
/* First.h 25: */
/* First.h 26: */
/* First.h 27: */
/* tmp.cpp 2: */
/* tmp.cpp 3: */
/* tmp.cpp 4: */int main()
/* tmp.cpp 5: */{
/* tmp.cpp 6: */First f;
/* tmp.cpp 7: */Second s;
/* tmp.cpp 8: */f.add(s);
/* tmp.cpp 9: */s.add(f);
/* tmp.cpp 10: */}
/* tmp.cpp 11: */
/* tmp.cpp 12: */


Ah! you think. First.h includes Second.h. Then Second.h tries to include First.h, but the inclusion guard prevents it. I have a classic Chicken-And-Egg scenario.

Then: Oh-ho! you think (for you are feeling very clever and pleased with yourself). I shall use a forward declaration of class First in Second.h instead of the #include "First.h".

So you replace #include "First.h" with class First; in Second.h and recompile but get:
Error E2450 Second.h 21: Undefined structure 'First'
Error E2449 Second.h 21: Size of 'memberVariable1' is unknown or zero
Error E2450 Second.h 21: Undefined structure 'First'
Error E2315 Second.h 14: 'add' is not a member of 'First', because the type is not yet defined in function Second::add(First)


So you look at line 21 of Second.h and find:
First memberVariable1; 

Oh! you think. I need to change this to a pointer because the compiler doesn't know who much space to allocate for a First object. So you replace First memberVariable1; with First* memberVariable1; and correct all the places in Second.h that use memberVariable1 (remembering to allocate it in the constructor and delete it in the destructor). So your Second.h now look like:
#if !defined(SECOND)
#define SECOND
class First;

class Second
{
public:
Second()
{
memberVariable2 = 0;
memberVariable1 = new First();
}
~Second()
{
delete memberVariable1;
}
void add(First f)
{
memberVariable1->add(f);
}
void add(Second s)
{
memberVariable2 += s.memberVariable2;
}
private:
First* memberVariable1;
int memberVariable2;
};
#endif


So you cross you fingers and recompile*³ but get:
Error E2450 Second.h 11: Undefined structure 'First' in function Second::Second()
Error E2315 Second.h 19: 'add' is not a member of 'First', because the type is not yet defined in function Second::add(First)


So you look at line 11 of Second.h and find:
memberVariable1 = new First(); 

Ah-ha! you think. The compiler doesn't know how to create a First object at this point. I need to #include "First.h". Then: Oh! you think. I tried that before and it just caused more errors. Then: Ah-ha! you think again. I'll seperate the declarations from the definitions. So you split your file into two new files, Second.h:
#if !defined(SECOND)
#define SECOND
class First;

class Second
{
public:
Second();
~Second();
void add(First f);
void add(Second s);
private:
First* memberVariable1;
int memberVariable2;
};
#endif


and Second.cpp:
#if !defined(SECOND_IMPL)
#define SECOND_IMPL
#include "Second.h"

Second::Second()
{
memberVariable2 = 0;
memberVariable1 = new First();
}

Second::~Second()
{
delete memberVariable1;
}

void Second::add(First f)
{
memberVariable1->add(f);
}

void Second::add(Second s)
{
memberVariable2 += s.memberVariable2;
}

#endif


And you recompile but get:
Error E2450 Second.cpp 8: Undefined structure 'First' in function Second::Second()
Error E2450 Second.cpp 17: Undefined structure 'First' in function Second::add(First)
Error E2315 Second.cpp 18: 'add' is not a member of 'First', because the type is not yet defined in function Second::add(First)


So you look at line 8 of Second.cpp and find:
memberVariable1 = new First();   

Ah! you think. The compiler still doesn't know how to create a First object at this point. I need to #include "First.h" and I can do it now because First.h doesn't #include "Second.cpp", so there won't be any Chicken-And-Egg problems.

So you do it and recompile and it build perfectly!

So the moral of the story is:
Always seperate declaration from definition. You can recombine later if you need to (i.e. a profiler highlights the function as a bottleneck).
Two classes can not each have a member of the other type. At least one of them must use a pointer or reference.
Only #include header files when necessary - i.e. if you are declaring a member of that class or calling a member function or using a member variable of that class (including constructors and destructors).
If you mention a class but don't use it, just use a forward declaration.

Enigma

*yes, you're in a very optimistic mood.
*²yes, you're still in a very optimistic mood.
*³for you are now feeling slightly less optimistic.

EDIT: OK, in a post that size there were bound to be typos!
EDIT2: OK, it was also inevitable that the first edit would mess up all the formatting!

[edited by - Enigma on February 1, 2004 12:29:33 PM]
Marty666
Marty666
Thanx, I just deleted everything and redid all of it exactly like you said.

Almost all errors are gone. A couple are back instead:

C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(3) : error C2653: ''std'' : is not a class or namespace name
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(3) : error C2143: syntax error : missing '';'' before ''<''
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(3) : error C2501: ''vector'' : missing storage-class or type specifiers
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\OBJLOADER\NukeM2\model.cpp(3) : error C2143: syntax error : missing '';'' before ''<''

i included and in line 3:
std::vector TempObjects;

It used to work, though. When I include it still gives the same errors. Should i link a .lib somewhere?

Thanx,
Marty
_ /__ /|| | || MtY | ||_____|/Marty
psykr
psykr
I think either you forgot to #include <vector>, or you included <vector.h> instead.
chronos
chronos
quote:
Original post by downgraded
More like
#include "b.h"

class B;

class A
{
B *m_somepointertoB;

};

#include "a.h"

class A;

class B
{
A *m_somepointertoA;

};

That doesn't look right. The whole point of forward declarations such as class A; is to not include the actual declaration at that point (which you do by including a.h). What you want is something like this:
// This is a.h 


class B;

class A
{
B *FunctionReturnsB();

};

// This is b.h


class A;

Class B
{
A *FunctionReturnsA();

};

// This is a.cpp


#include "a.h"
#include "b.h"

B *A::FunctionReturnsB() {
// ...

}

// This is b.cpp


#include "b.h"
#include "a.h"

A *B::FunctionReturnsA() {
// ...

}


[edited by - chronos on February 1, 2004 12:40:06 PM]
Marty666
Marty666

seems logical, chronos, but it works the way downgraded said aswell. The problem left is that my compiler doesn''t recognise the std namespace. I included and (notice: no .h). in the header file.
this is the line that gives errors

std::vector TempObjects;
PS: last message didn''t contain the <..> parts, use [code] and
in your message to display it.


_ /__ /|| | || MtY | ||_____|/Marty
EL
EL
quote:
Original post by Marty666
seems logical, chronos, but it works the way downgraded said aswell. The problem left is that my compiler doesn''t recognise the std namespace. I included <stdlib.h> and <vector> (notice: no .h). in the header file.
this is the line that gives errors

std::vector<t_model_object> TempObjects;



First of all, stdlib is a C-header. In C++ you should include <cstdlib> (the same goes for other C-headers, leave the .h and put a ''c'' in front of it).

Now on the std namespace. Are you sure you didn''t state using std; somewhere?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.