zyklische Abhängigkeiten und forward declarations
-
Hi, ich habe folgende zyklische Abhängigkeit in meinem Design:
scene.hppenthält die Deklaration einer KlasseScene, die eine Spielszene beschreibt.gameobject.hppenthält die Deklaration einer KlasseGameObject, die ein einzelnes Objekt der Spielszene beschreibt.- Eine
Scenebesitzt mehrere Instanzen vonGameObject=>scene.hppbenötigt das SymbolGameObject. - Ein
GameObjectkennt dieScenezu der es gehört =>gameobject.hppbenötigt das SymbolScene
.. also eine klassische zyklische Abhängigkeit. Ich wüsste nicht wie ich diese Abhängigkeit sinnvoll brechen kann. Ist es sinnvoll und legitim hier forward declarations zu verwenden und erst in der Implementierung die entsprechenden Header einzubinden? D.h.
// scene.hpp class GameObject; // Rest der ursprünglichen Deklaration// scene.cpp #include "scene.hpp" #include "gameobject.hpp" // Rest der ursprünglichen Implementierung// gameobject.hpp class Scene; // Rest der ursprünglichen Deklaration// gameobejct.cpp #include "gameobject.hpp" #include "scene.hpp" // Rest der üblichen ImplementierungDenkbare wäre auch, die forward declaration nur in einem der Header (d.h. z.B.
class Scene;ingameobject.hppzu machen und im anderen Header schon mitincludezu arbeiten (d.h.#include "gameobject.hppinscene.hpp).Rein technisch funktioniert das .. nur ist die Frage ob das hier noch best practise oder eher schon "Bekämpfung der Symptome" ist...

LG Glocke
-
Meiner Meinung nach macht es immer Sinn mit Forward Declarations zu arbeiten und den Header nur dann einzubinden, wenn die komplette Klassendefinition auch tatsächlich benötigt wird. Das hilft nicht nur solche zyklischen Abhängigkeiten zu brechen, sondern reduziert auch generell die Abhängigkeiten der Header untereinander. Wenn so ein Projekt mal größer wird führt ansonsten jede kleine Änderung in einer Header-Datei dazu, dass große Teile des Projekts neu kompiliert müssen (weil die in den cpp-Dateien eingebundenen Header dann oft "über etliche Ecken" von dem Header abhängig sind, an dem du gerade Änderungen vorgenommen hast)
Generell: Wenn du nur einen (Smart-)Pointer auf die Klasse verwendest, dann empfiehlt sich eine solche Forward Declaration. Wenn du von der Klasse ableitest, oder diese z.B. ein nicht-Pointer-Member im aktuellen Header ist, kommst du allerdings nicht drum herum, auch den Header der Klasse einzubinden, weil dafür die komplette Definition bekannt sein muss.
Wenn in deinen Headern nur (Smart-)Pointer auf die andere Klasse auftreten (ohne diese zu kennen vermute ich das mal), würde ich also aus den o.g. Gründen in beiden mit einer Forward Declatation abreiten und die jeweiligen Header erst in der .cpp-Datei einbinden (dort, wo die komplette Klassendefinition auch wahrscheinlich tatsächlich erst benötigt wird).
Finnegan
-
Die <GameObject.h> kann auch am Anfang die Scene vorausdeklarieren und dann die <Scene.h> am Ende inkludieren. Dann haben sich die beiden Headers doch gegenseitig inkludiert, ohne zu weinen.