Frage zu Klassen [gelöst]
-
Hi,
Ich habe zwei Klassen (A und B). Beide benötigen sich gegenseitig.A a, a1, a2; B b, b1, b2; a = b1 + b2; b = a1 + a2;Nur wenn ich die Operatoren so überlade, sagt der Compiler, dass die Klasse undefiniert ist...
//A.h #ifndef _A #define _A #include "B.h" class A { public: A(); A operator+(const A& other) { //... } A operator=(const B& other) { //... } }; #endif //B.h #ifndef _B #define _B #include "A.h" class B { public: B(); B operator+(const B& other) { //... } B operator=(const A& other) { //... } }; #endifWie kann ich das Problem lösen ?
-
Das Ergebnis von b1 + b2 ist natürlich wieder vom Typ B und nicht vom Typ A. Du bräuchtest also noch zusätzlich Konvertierungsoperatoren A->B und B->A.
-
Deshalb
A operator=(const B& other) { //... }und
B operator=(const A& other) { //... }
-
Zyklische Includes. Böse ganz böse.
Lies das durch:
http://www.drakon.ch/?id=&offset=2&mobile=0&show_entry=77
-
Aber das müsste ich doch mit "#ifndef" und "#define" umgehen...
Ich brauche halt "A=A+B" und "B=A+B"
Also ein Operator+ der aus A und B B oder A macht
Ich hatte auch "class B;" schon, aber es heißt wieder, dass B undefiniert ist.
Das Problem habe ich mit dem vorherigen Code:
error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.Das Problem mit "class B;":
error C2027: Verwendung des undefinierten Typs "B"
-
Sorry, hab den Code nicht ganz gelesen.
Du musst die Implementierungen der Funktionen in die cpp-Dateien auslagern. Dann klappts auch mit der forward declaration.
Das Problem umgehst du übrigens nicht mit #ifndef etc. Geh die Textersetzung (die ein #include nunmal ist) mal ganz explizit durch.
-
Nein. Damit verhinderst du nur, dass er die Klasse lesen kann. Gehs einfach mal von Kopf durch.
Sagen wir A.h wird zuerst vom Präprozessor behandelt, dann sieht er, dass du ja noch B.h inkludierst, also geht er dort hin und holt die rein. Das dortige A.h wird ignoriert (wegen dem Headerguard) und du hast für die Klasse B keine Definition von A. Nach der Definition von B kommt dann die Definition von A (wieder in A.h zurück).
Wie gesagt lies meinen Beitrag durch. Dort steht, wie du das lösen kannst (ein sehr häufiges Problem).
-
Aber wie ?
Ich habe A und B in Sourcedateien und in den Headern "class A;" und "class B;",
aber der gibt wir wieder die Fehlererror C2027: Verwendung des undefinierten Typs "B" Siehe Deklaration von 'B' error C2228: Links von ".x" muss sich eine Klasse/Struktur/Union befinden.Also jetzt ohne Präprozesserbefehle.
-
Wenn du den kompletten Beitrag gelesen hättest, dann wüsstest du wie. Er ist nicht so lange und dort steht alles, was du wissen musst..
-
Wenn wir unsere car-Klasse ansehen, dann sehen wir, dass da lediglich Zeiger auf human gebraucht werden und eine Funktion von human wird auch nirgends aufgerufen.
Und wie soll ich das dann bei Operatorüberladung machen ?
Muss ich wirklich ALLES auf Zeiger umstellen ?
-
DarkShadow44 schrieb:
Und wie soll ich das dann bei Operatorüberladung machen ?
Du sollst die Funktionen nicht inline definieren. Definiere sie in der .cpp-Datei, während im Header lediglich die Deklaration steht. So wie es drakon in seinem Artikel erwähnt, lies den doch endlich!
-
DarkShadow44 schrieb:
Wenn wir unsere car-Klasse ansehen, dann sehen wir, dass da lediglich Zeiger auf human gebraucht werden und eine Funktion von human wird auch nirgends aufgerufen.
Und wie soll ich das dann bei Operatorüberladung machen ?
Muss ich wirklich ALLES auf Zeiger umstellen ?
Nein. Lediglich Datenmember müssen dafür Zeiger sein. Parameter, Rückgabewerte können ganz normale Objekte sein, weil die gar nicht interessieren für die Grösse des Objektes, dass du definierst.
Ich hätte hier jetzt fast die Lösung gepostet, aber ich finde, dass du lieber nochmal genau nachlesen solltest. Das bringt dir auf die Dauer mehr, als wenn wir dir hier die Lösung präsentieren.
-
OK. Sorry, ich wusst nicht, dass man auch die Operatorüberladungs-Definition auslagern kann...

Ich hatte die bisher immer im Header ^^Jetzt gehts, danke

-
Überladene Operatoren sind im Grunde genommen ganz normale Funktionen. Sie haben hauptsächlich eine syntaktische Sonderbehandlung (und dadurch werden auch Dinge wie Assoziativität und Priorität wichtig).
-
Das sind ganz normale Funktionen, mit ein wenig Syntax Sugar.
