In C++, I have a problem with a double include:
File stuffcollection.h
#pragma once
#ifndef STUFFCOLLECTION_H
#define STUFFCOLLECTION_H
#include "Stage.h"
class Stuffcollection {
public:
bool myfunc( Stage * stage );
};
#endif // STUFFCOLLECTION_H
File stage.h:
#pragma once
#ifndef STAGE_H
#define STAGE_H
#include "Stuffcollection.h"
class Stage {
// stuffcollection used in stage.cpp
};
#endif // STAGE_H
Compiler Error:
\Stuffcollection.h|(line were bool myfunc is declared)|error: 'Stage' has not been declared|
||=== Build finished: 1 errors, 0 warnings ===|
Can someone please explain why this happens and how it can be solved? I already use include guards and the pragma once preprocessor directive and it just doesn't work.
(If I remove #include "Stuffcollection.h"
from stage.h and comment out the respective lines that are using it in stage.cpp, the rest of my code works fine. It's really just when including Stuffcollection into stage that it suddenly stops working.)
PS: stage is just one example, I use stuffcollection in almost every other file too, and everytime I get this problem.
EDIT: I fol开发者_如何学Golowed what has been suggested, and now the problem is invalid use of incomplete type
, i.e. while the answers given solve the problem of the circular dependency they do not solve the problem I am dealing with. My problem is continued in Circular Dependencies / Incomplete Types.
EDIT: Both solved now.
You have a Circular Dependency. Instead use Forward Declaration in Stuffcollection.h
#pragma once
#ifndef STUFFCOLLECTION_H
#define STUFFCOLLECTION_H
//#include "Stage.h" //<------------------Don't Do This
class Stage; //<------------------Do This
class Stuffcollection {
public:
bool myfunc( Stage * stage );
};
#endif // STUFFCOLLECTION_H
Rationale:
You can use the forward declaration in above snippet because, Stuffcollection.h
only uses pointer to Stage
.
Explanation:
Using a forward declaration of class Stage
, the compiler does not know the composition of it nor the members inside it, the compiler only knows that Stage
is a type
. Thus,
Stage
is an Incomplete type for the compiler. With Incomplete types , One cannot create objects of it or do anything which needs the compiler to know the layout of Stage
or more than the fact that Stage
is just an type. Since pointers to all objects need just the same memory allocation, You can use the forward declaration when just referring to Stage
as a pointer.
You can use Forward Declarations to get over your circular dependency problems.
Further Read:
When to use forward Declarations?
It's a circular dependency. Don't make them. This one you can resolve by replacing #include "Stage.h"
in stuffcollection.h with a forward declaration of Stage
(i.e. class Stage;
).
Instead of the #include
you can use forward declarations i.e. class Stage;
and class Stuffcollection
. It also has the benefit of reducing dependencies.
精彩评论