Circular Dependencies / Incomplete Types
In C++, I have a problem with circular dependencies / incomplete types. The situation is as follows:
Stuffcollection.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 开发者_StackOverflow社区stuffme;
myvar = stuffme.myfuncTwo();
}
- If I keep the includes as shown above, I get the compiler error
spritesheet has not been declared
in Stuffcollection.h (line 4 in the above). I understand this to be due to a circular dependency. - Now if I change
#include "Spritesheet.h"
to the Forward Declarationclass Spritesheet;
in Stuffcollection.h, I get the compiler errorinvalid use of incomplete type 'struct Spritesheet'
in Stuffcollection.cpp (line 2 in the above). - Similarly, if I change
#include "Stuffcollection.h"
toclass Stuffcollection;
in Spritesheet.h, I get the compiler erroraggregate 'Stuffcollection stuffme' has incomplete type and cannot be defined
in Spritesheet.cpp (line 2 in the above).
What can I do to solve this problem?
You should include Spritesheet.h
in Stuffcollection.cpp
Just use forward declaration in the header file not the cpp file, that solves the circular dependency of the header file. The source file has no circular dependency actually.
Stuffcollection.cpp
needs to know the complete layout of class Spritesheet
(because you dereference it), So you need to include the header which defines the class Spritesheet
in that file.
From your previous Q here, I believe that class Stuffcollection
is used in the class declaration of Spritesheet
header file and hence the above proposed solution.
Use this form for your nested includes:
Stuffcollection.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 I follow:
- Don't include an include from an include, dude. Prefer forward declarations if possible.
- Exception: include system includes anywhere you want
- Have CPP include everything it needs, not relying upon H recursively including it files.
- Always use include guards.
- Never use
pragma
Spritesheet.h
doesn't need to include Stuffcollection.h
, since no Stuffcollection
is used in the class declaration of Spritesheet
. Move that include line to Spritesheet.cpp
instead and you should be fine.
精彩评论