Вопрос

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 followed 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top