P
Scarabol schrieb:
Hi,
ich hab mittlerweile auch das Problem, dass ich die Klassen soweit ineinander verschachtelt habe, dass ich immer nur die Meldung "Verwendung des undefinierten Typs..." bekomme wenn ich die Reihenfolge der Includes ändere oder neue hinzufüge :-((
Um sowas aufzuräumen gehe ich meist wie folgt vor:
- nehmen wir an, ich hab eine X.cpp und die zugehörige X.hpp. Dann stelle ich in der X.cpp die X.hpp als erstes #include ein. Damit krieg ich als erstes Fehlermeldungen aus diesem Header (direkt oder indirekt aus den Headern, die X.hpp einbindet), danach aus den anderen Headern, die X.cpp einbindet, danach aus X.cpp selber.
- ich kommentiere sämtliche #includes und forward-decls aus X.hpp aus, genauso alle #includes aus X.cpp, mit Ausnahme von X.hpp. Ich versuche X.cpp zu compilieren. Ich kriege zuerstmal Fehlermeldungen aus X.hpp über unbekannte Typen usw. Zu jedem Fehler entscheide ich, ob eine forward-decl reicht oder ob ein #include mit der entsprechenden Klassendefinition nötig ist.
danach nächster compile-Versuch. Jetzt bekomme ich evtl. Fehlermeldungen aus den in X.hpp eingebundenen Headern. Falls das so ist gehe ich für jeden Header Y.hpp der einen Fehler erzeugt das Selbe Procedere mit seiner Y.cpp durch, quasi rekursiv. (Die Rekursion terminiert dank der Includequards)
- ich hab jetz nurnoch Fehler in der X.cpp. Ich binde für jeden Fehler den nötigen Header wieder ein, ab und an reicht auch hier eine Forward-decl, z.B. wenn ich nur Pointer von A nach B reiche ohne auf das dahinterliegende Objekt zuzugriefen.
- ich freu mich, dass ich die Hälfte der vorher auskommentierten #includes nicht wieder einkommentieren musste und deshalb einige Compile-Abhängigkeiten rauswerfen konnte. Das gleiche Spiel kann ich jetzt auch mit dem Linker machen, indem ich zuerst garkeine Bibliotheken mitlinke und nachschaue, was ich wirklich dazulinken muss. Das trifft aber eher nur dann zu wenn man an einer größeren Software arbeitet wo mehrere hundert .libs gegenseitige Abhängigkeiten haben.
Das Ganze ist ziemlich umständlich und kostet Zeit. Man kanns etwas abkürzen, wenn man z.B. die unbedingt nötigen #includes schon vorher sieht (Basisklassen und Member, die keine Referenzen oder Pointer sind). Aber allgemein kann mir der Compiler selbst am besten sagen was er braucht so dass ich nicht voreilig alles #include was mir zu dem Thema in den Sinn kommt. So eine Aufräumaktion starte ich auch nur, wenn ich ein größeres Refactoring hinter mir habe oder neue Funktionalität eingebaut habe wo neue Klassen entstanden sind und/oder größere Codeteile umgezogen sind bzw. sich grundlegend geändert haben. Aber hin und wieder lohnts sich und wenn der Build der Komponente dadurch ein paar Sekunden schneller geht und die Zusammenhänge übersichtlicher werden rechnet sich der Aufwand.