C circular dependency
Seems like you shouldn't need to include anything in any of the files. A forward declaration of the relevant types should be sufficient:
#ifndef MapTest_vertex_h
#define MapTest_vertex_h
struct edgelist;
typedef struct
{
char* name;
float x, y;
edgelist* edges; // C++ only - not C
} vertex;
#endif
etc. In C coding, you have to write:
struct edgelist;
typedef struct
{
char* name;
float x, y;
struct edgelist* edges;
} vertex;
Circular dependency between C header files
The solution is to simply use some manner of program design. Each "object"/"module" in your program should consist of one h file and one c file. The h file is the public interface. Each such object should only be concerned with its own designated task. It should only include the resources needed to perform that task.
With such a design, there should never be any circular dependencies, or the design is flawed. You should not fix a bad design with various code tricks, you should re-do the design.
But of course the same resource could be included multiple time from different parts of the code. This is why we always use header guards in every single h file.
Solving a circular dependency - C
It can be useful to define enums in their own file(s), and if you do that here, your problem will disappear.
How to resolve circular struct dependencies in C
The way to do this is to pre-define the structs using empty definition
typedef struct _A A;
typedef struct _B B;
typedef struct _A {
B *b;
} A;
typedef struct _B {
A a;
} B;
You can put the pre-definitions in a global include file to include from wherever you need.
`
C++: Circular dependency with static members
You can't define A::func()
referencing B's members before at least declaring B. A forward declaration of B is just saying that a class called B will exist, nothing about B's members. You can however declare A::func()
.
One way to do this is the typical .h file / .cpp file combination. If for whatever reason you want all of A and B -- declaration and definition -- in one file it can be done as below:
class A {
public:
static int somethingStatic;
int func();
};
class B {
public:
static int somethingStatic;
int func() {
return A::somethingStatic;
}
};
int A::func() {
return B::somethingStatic;
}
int A::somethingStatic = 42;
int B::somethingStatic = 5;
Notice that in this case it is no longer even necessary to forward declare B, as the declaration of A is not dependent on B at all. The same would be true if you broke out the definition of both into a separate .cpp file.
Handling circular dependencies in C++
Since the C++17 standard you don't need the full EntityBase
class definition for the Scene
class, only a forward declaration:
#pragma once
#include <vector>
#include <string>
class EntityBase; // Forward declaration
class Scene
{
public:
std::vector<EntityBase> entities;
std::string name;
Scene(std::string name);
void addToScene(EntityBase& entityBase);
};
You of course need to include EntityBase.h
anywhere where the entities
vector is used, most notable in the Scene.cpp
source file.
Since EntityBase
is using an actual instance of Scene
you can't do the same with that class and the EntityBase.h
header file. Here you must include the Scene.h
header file.
If you build targeting an older C++ standard (C++14 or earlier) then you must have the full definition of the EntityBase
class for the vector.
As a possible workaround either make entities
a vector of pointers to EntityBase
; Or make EntityBase::scene
a pointer and use forward declaration in the EntityBase.h
header file instead. Or a combination of both.
Resolve circular typedef dependency?
Forward-declare one of the structs:
struct people;
typedef struct {
/* same as before */
struct people* friends;
} Person;
typedef struct people {
/* same as before */
} People;
Related Topics
Serial Port (Rs -232) Connection in C++
Recursive Lambda Functions in C++14
How to Use C++ Std::Ostream with Printf-Like Formatting
C++: Wrapping Vector<Char> with Istream
Compile-Time Map and Inverse Map Values
Using Sfinae for Template Class Specialisation
Why Use ++I Instead of I++ in Cases Where the Value Is Not Used Anywhere Else in the Statement
How to Forward Declare a Template Class in Namespace Std
How to Find Longest Common Substring Using C++
Exclude Source File in Compilation Using Makefile
What's the Best Way to Check If a File Exists in C++? (Cross Platform)
Safely Override C++ Virtual Functions
Iterating Through a Lua Table from C++
How to Pass a C++ Lambda to a C-Callback That Expects a Function Pointer and a Context