Circular dependencies / incomplete types

In C ++, I have a problem with circular dependencies / incomplete types. The situation is as follows:

Stuffpollection.h

#include "Spritesheet.h"; class Stuffcollection { public: void myfunc (Spritesheet *spritesheet); void myfuncTwo (); }; 

Stuffcollection.cpp

 void Stuffcollection::myfunc(Spritesheet *spritesheet) { unsigned int myvar = 5 * spritesheet->spritevar; } void myfunc2() { // } 

Spritesheet.h

 #include "Stuffcollection.h" class Spritesheet { public: void init(); }; 

Spritesheet.cpp

 void Spritesheet::init() { Stuffcollection stuffme; myvar = stuffme.myfuncTwo(); } 
  • If I save my inbox as shown above, I get the spritesheet has not been declared compiler error in Stuffcollection.h (line 4 in the above). I understand that this is due to cyclical dependence.
  • Now, if I change #include "Spritesheet.h" to Forward Declaration class Spritesheet; in Stuffcollection.h, I get a compiler error invalid use of incomplete type 'struct Spritesheet' in Stuffcollection.cpp (line 2 above).
  • Similarly, if I change #include "Stuffcollection.h" to class Stuffcollection; in Spritesheet.h, I get an aggregate 'Stuffcollection stuffme' has incomplete type and cannot be defined compiler error aggregate 'Stuffcollection stuffme' has incomplete type and cannot be defined in Spritesheet.cpp (line 2 above).

What can I do to solve this problem?

+4
source share
3 answers

You must include Spritesheet.h in Stuffcollection.cpp
Just use the forward declaration in the header file, not the cpp file, which allows the header file to loop around. The source file has virtually no circular dependency.

Stuffcollection.cpp needs to know the full layout of the Spritesheet class (because you spot it). Therefore, you need to include a header that defines the Spritesheet class in this file.

From your previous Q here , I believe that the Stuffcollection class Stuffcollection used in the class declaration of the Spritesheet header file and therefore the solution proposed above.

+3
source

Spritesheet.h does not need to include Stuffcollection.h , because the Spritesheet class Spritesheet does not use Stuffcollection . Move by including the line in Spritesheet.cpp and you should be fine.

+2
source

Use this form for your nested inclusions:

Stuffpollection.h

 #ifndef STUFFCOLLECTION_H_GUARD #define STUFFCOLLECTION_H_GUARD class Spritesheet; class Stuffcollection { public: void myfunc (Spritesheet *spritesheet); void myfuncTwo (); }; #endif 

Stuffcollection.cpp

 #include "Stuffcollection.h" #include "Spritesheet.h" void Stuffcollection::myfunc(Spritesheet *spritesheet) { unsigned int myvar = 5 * spritesheet->spritevar; } void Stuffcollection::myfuncTwo() { // } 

Spritesheet.h

 #ifndef SPRITESHEET_H_GUARD #define SPRITESHEET_H_GUARD class Spritesheet { public: void init(); }; #endif 

Spritesheet.cpp

 #include "Stuffcollection.h" #include "Spritesheet.h" void Spritesheet::init() { Stuffcollection stuffme; myvar = stuffme.myfuncTwo(); } 

General rules that I adhere to:

  • Don't include include from include, dude. Assume forward declarations, if possible.
    • Exception: turn on the system anywhere.
  • CPP has everything you need without relying on recursively H, including its files.
  • Always use protective devices.
  • Never use pragma
+2
source

All Articles