Was du hier hast ist ein klassischer Fall eines zirkulären
#include. Nehmen wir an du hast z.B. ein .cpp File welches
|
C-/C++-Quelltext
|
1
|
#include "config.h"
|
macht.
Wir includen also
"config.h". In
"config.h" steht zunächst ein
#pragma once. Der Compiler merkt sich an dieser Stelle, dass
"config.h" bereits inkludiert wurde. Dann wird in
"config.h", bevor noch irgendwas anderes passiert,
"main.h" inkludiert.
"main.h" inkludiert wiederum
"config.h". Der Compiler schaut nach, ob
"config.h" schon inkludiert wurde und merkt, dass es schon inkludiert wurde. Daher wird der
#include "config.h" an dieser Stelle übersprungen. Direkt danach inkludiert
"main.h" den Header
"game.h", welcher wiederum
"main.h" inkludiert.
"main.h" hatte ebenfalls ein
#pragma once und wurde an dieser Stelle schon inkludiert, daher wird der
#include "..\main.h" übersprungen. Nach dem übersprungenen
#include kommt direkt die Definition des Namespace
ggame und der Klasse
game. Bachte, dass wir auf diesem Weg an der Definition der Klasse
game angelangt sind, bevor der Hauptteil von
config.h durchlaufen wurde (weil
config.h vor der Definition der Klasse
config erstmal
main.h included, welches wiederum
game.h included, welches zwar indirekt
config.h included, aber weil wir an dieser Stelle aus
config.h selbst kommen, wird der include wegen
#pragma once übersprungen). Wenn wir dann also zur Zeile
|
C-/C++-Quelltext
|
1
|
cconfig::config *configuration;
|
kommen, ist nicht bekannt, was
cconfig::config sein sollte.
Die Lösung des Problems: Inkludiere immer nur was du wirklich brauchst. In deiner Definition von
game musst du die Definition von
config z.B. (noch) nicht kennen, weil du dort nur einen Member deklarierst, der nur ein Pointer auf eine
config ist. In diesem Fall reicht eine
Forward-Declaration von config aus:
|
C-/C++-Quelltext
|
1
|
namespace cconfig { class config; }
|
statt dem
#include der vollständigen Definition…