Merkwürdiges cast-Problem?
-
Hallo

struct f {}; struct fn : public f {}; class e { e* _e2; f* _f2; public: e* getE() { return _e2; } void getE( e* E ) { _e2 = E; } f* getF() { return _f2; } void getF( e* E ) { _f2 = F; } }; struct en : public e { en* getE() { return e::getE(); } void setE( en* E ) { e::setE( E ); } fn* getF() { return e::getF(); } void setF( en* F ) { e::setF( F ); } }; int main() { en* a = new en(); a->setE( new en() ); a->getE()->setF( new fn() ); e* b = a; a->getE()->getF(); b->getE()->getF();// Anderer Zeiger }Meine Klassen lassen sich auf e und f reduzieren. Das Problem tritt in den letzten beiden Zeilen auf. Die Speicheradressen unterscheiden sich aus unerklärlichen Gründen. Leider konnte ich den Bug nicht reproduzieren (d.h dieses beispiel sollte eigendlich funktionieren). Kann mir evtl jemand sagen wie ich den Grund herausfinden kann?
Werde bald ausführlicher, Danke!

-
Der Code dürfte hinten und vorne nicht kompilieren

Alleine schon
en* getE() { return e::getE(); }, da e::getE() ja ein e* zurückgibt, was ja ge-upcast-ed werden müsste.
-
Badestrand schrieb:
Der Code dürfte hinten und vorne nicht kompilieren

Alleine schon
en* getE() { return e::getE(); }, da e::getE() ja ein e* zurückgibt, was ja ge-upcast-ed werden müsste.Dort vermute ich vielleicht auch ein Problem. Das hab ich vergessen hinzuschreiben aber ich mach das so:
return (en*)e::getE();Entschuldigt bitte weiter kleine Fehlerchen

-
Also bei mir ist die Ausgabe beider Zeiger identisch.
struct f {}; struct fn : public f {}; class e { e* _e2; f* _f2; public: e* getE() { return _e2; } void setE( e* E ) { _e2 = E; } f* getF() { return _f2; } void setF( f* F ) { _f2 = F; } }; struct en : public e { en* getE() { return static_cast<en*>(e::getE()); } void setE( en* E ) { e::setE( E ); } fn* getF() { return static_cast<fn*>(e::getF()); } void setF( fn* F ) { e::setF( F ); } }; int main() { en* a = new en(); a->setE( new en() ); a->getE()->setF( new fn() ); e* b = a; std::cout << a->getE()->getF() << std::endl; std::cout << b->getE()->getF() << std::endl; }
-
Mach mal dynamic_casts anstatt C-Casts. So zur Sicherheit. Oder allerwenigstens static_casts. Das hat nicht nur mit "C++-Ästhetik" zu tun.
Zeigen beide Zeiger auf ein gültiges Objekt / das selbe Objekt, auch wenn ihre Adressen anders sind? Es sind ja immerhin Zeiger auf ein f und ein fn. Siehe nächster Punkt.
Ist Mehrfachvererbung/virtuelle Vererbung im Spiel? Dann müssen sich die Zeiger im Regelfall sogar unterscheiden, weil beim Down-Cast der Offset entsprechend angepasst werden muss.
-
Oh ich spüre schon des Rätzels lösung!! Ja, ich habe eine virtuelle Funktion. Deshalb verändert sich auch der Zeiger leicht. (Sie bleibt immer ungefähr die Selbe). Jedoch scheint mein Objekt dann nicht gültig zu sein!
Ich werde heut Abend mal dynamic_cast probieren.
Muss ich auch beim downcast eine solche cast-Funktion anwenden??
@Badestrand: Genau das ist das Problem. Ich kann den Bug nicht reproduzieren.
-
Pigeon@work schrieb:
Muss ich auch beim downcast eine solche cast-Funktion anwenden??
Beim Down-Cast ja. Beim Up-Cast kann der Compiler das von alleine (außer bei virtuellen Basisklassen).
Bin nicht ganz sicher, ob du dir sicher bist, aber ein Down-Cast ist von einer Basis-Klasse auf eine abgeleitete Klasse. Up-Cast sollte dann klar sein

-
Pigeon@work schrieb:
Oh ich spüre schon des Rätzels lösung!! Ja, ich habe eine virtuelle Funktion. Deshalb verändert sich auch der Zeiger leicht. (Sie bleibt immer ungefähr die Selbe). Jedoch scheint mein Objekt dann nicht gültig zu sein!
Das ist wirr. dynamic_cast wird dein Problem wahrscheinlich nicht lösen. Was du aber auf jeden Fall nicht tun sollstest, ist die Verwendung von C-Style casts, denn deren Bedeutung kann subtil variieren ohne dass dies bei der Verwendung offensichtlich wird. Richtig wäre, diese Casts im Original durch static_cast zu ersetzen - bekommst du dann einen Fehler beim Compilieren, ist die Ursache des Problems klar.
-
So es geht... Einmal musste ich dynamic_cast, das andere Mal static_cast anwenden***. Warum habe ich (NOCH) keine Ahnung .... ich danke euch

***
GCC schrieb:
Fehler: dynamic_cast »((const en_t*)this)->en_t::<anonymous>.e_t::nextF()« (des Typs »class f_t*«) in Typ »class fn_t*« (source type is not polymorphic) kann nicht vorgenommen werden
