Problem mit mehreren Klassen
-
Hallo.
Ich habe ein Problem: Ich habe mehrere Klassen und in einer dieser Klassen ist eine Variable auf die viele Klassen zugreifen müssen. Also deklariere ich die Funktion der Klassen die zugreifen müssen als friend. Jede Klasse hat ihre eigene Header-Datei. Dann habe ich da Noch eine letzte Hauptdatei die alles zusammenführt.Main.cpp
#include "a" #include "b" ...a.h
class a { friend void b::do(); protected: LPDIRECT3DDEVICE9 d3dDevice; //sehr wichtig ... };b.h
class b { void do () {a::LPDIRECT3DDEVICE9; } };So weit so gut. Jetzt kommen aber unterschiedliche Fehlermeldungen, je nachdem, in welcher Reihenfolge ich die Dateien include. Bei a zuerst: error C2653: 'a': Keine Klasse oder Namespace. Bei b zuerst: error C2653: 'b': Keine Klasse oder Namespace + error C2275: 'LPDIRECT3DDEVICE9': Ungültige Verwendung dieses Typs als Ausdruck. Hoffe, ihr versteht das Prob.
-
Wenn Du den Compiler mit einer Quelldatei fütterst, ist das dann so ziemlich alles, was er "sieht". Er schaut nicht in anderen Quelldateien nach, um zu sehen, ob da noch irgendwelche Klassendefinitionen drin sind, die benötigt werden.
Das bedeutet, dass Du im Header a.h noch ein #include "b.h" oben einfügen solltest, da a.h von b.h abhängt. In deinem Fall gilt die Abhängigkeit sogar beidseitig -- sie ist "zirkular". Das ist ganz schlecht -- aber auch unnötig. Die Definition der Elementfunktion ("do" ist übrigens kein gültiger Bezeichner, da es ein Schlüsselwort ist) kannst Du in b.cpp auslagern, so dass b.h nicht mehr von a.h abhängt.
Gruß,
SP
-
Danke für die schnelle und gute Antwort!
1. Das mit do stimmt, ist aber eigentlich auch anders benannt. Habe nur nich richtig nachgedacht
2. Ich verstehe nicht was das Auslagern bringen soll. Die Variable ist doch immernoch nur in der Klasse a definiert und nur weil ich die Funktion auslager, kann die Klasse b doch nicht einfach darauf zugreifen, oder?
3. Beim gegenseitigen Include sagt er auf einmal: fatal error C1014: Zu viele Headerdateien: Tiefe = 1024. Habe nur die gegenseiteigen Includes und dann noch ein paar normale Standart DirectX includes... Was kann das also bedeuten???
-
Habe es selsbt herausgefunden: Hatte die Includes nicht durch Mehrfacheinbindung geschützt. So haben sie sich immer wieder gegenseitig eingebunden.
Leider funktioniert das mit dem Inlcude nicht. Es kommen die selben Fehler. Also wenn du mir das erklärst was das Auslagern bringen soll, würde ich ja gerne diese Methode nehmen
-
Die Prinzip ist wirklich ganz einfach: Sorg dafür, dass es keine zirkularen Abhängigkeiten gibt. Damit meine ich, dass wenn Header a.h von Header b.h aabhängt, dann Header b.h nicht von Header a.h abhängen darf. Oder graphenteoretisch formuliert: Wenn jede Datei ein Knoten ist und eine gerichtete Kante von Knoten A nach Knoten B bedeutet, dass A die Datei B "included"; dann darf es in diesem Graph keine Kreise geben.
d3dDevice ist übrigends eine Objektvariable. Du brauchst also ein Objekt vom Typ "a", um auf das Element "d3dDevice" zugreifen zu können.
Tipp1: Überdenk Dein Design. Vermeide "friend" wenn möglich, weil es Abhängigkeiten schafft.
Tipp2: Mach Dich zum Thema "Include-Guards" schlau.
Jetzt kommt hier noch ein eher sinnloses Beispiel:
a.h
#ifndef MY_A_H_INCLUDED #define MY_A_H_INCLUDED #include "b.h" class A { private: friend void B::foo(); static int bescheuert; }; #endifb.h
#ifndef MY_B_H_INCLUDED #define MY_B_H_INCLUDED class B { public: void foo(); }; #endifa.cpp
#include "a.h" int A::bescheuert = 0;b.cpp
#include "a.h" #include "b.h" void B::foo() { A::bescheuert += 99; }Abhängigkeitsgraph:
a.cpp -->_a.h -->_b.h /| /| / / b.cpp ------'(Beachte: Es gibt keine Kreise!)
Gruß,
SP
-
Irgendwas klappt da nicht. Wenn ich meinen Code so aufteile wie du es gesagt hast, bekomme ich ca 100 Fehler in der WinBase (!!!) das heißt ja, das ich mal wieder einen Fehler gemacht habe. Außerdem weiß ich nciht was an einer gegenseitigen Abhängigkeit schlecht ist? Und ohne friend weiß ich echt nicht wie ich meine Klassen designen soll!
MfG TB_D
PS: Klar weiß ich was Include Guards sind, hatte nur vergessen meine Includes da rein zu schreiben und im geposteten Code habe ich sie vergessen