Hallo,
hier eine Frage an die Programmierer und Compiler-Interna-Kenner: Ich habe unter C++ 3 Klassen:
Klasse_A - stellt die Methoden 'setValue(int)' und 'int getValue()' zur Manipulation der privaten Variablen 'int mValue' zur Verfügung
Klasse_B - ist von Klasse A und QWidget abgeleitet
Klasse_C - hat ein Objekt von Klasse B als parent und ist auch von QWidget abgeleitet
Folgender Bug tritt nun bei meinem Programm auf: Wenn ich mir ein Objekt der Klasse_B auf dem Heap allokiere und dann die Methoden setValue() und getValue() benutze, wird die Variable mValue ordnungsgemäß verändert bzw. zurückgeliefert. Wenn ich nun aber in einer Methode des Objekts der Klasse_C, das oben genanntes Objekt als parent hat, folgenden Code ausführe, erhalte ich einen falschen Wert zurück...
Klasse_A *ptr = (Klasse_A*)parentWidget(); int retval = ptr->getValue()
Ich habe mit dem Debugger etwas herumgespielt und herausgefunden, das, wenn ich aus dem Klasse_C-Objekt heraus die Methode getValue() aufrufe, die Variable mValue plötzlich an einer anderen Speicheradresse liegt und zwar an der, an der auch 'ptr' beginnt... :/ Deswegen wird auch nicht der ehemalige Inhalt von mValue zurückgeliefert, sondern ein nummerischer Wert, der an der Speicheradresse von 'ptr' steht.
Das parentWidget() ist Qt-spezifisch und gibt einen Pointer auf das parent-Objekt zurück. Da es in vielen Programmen verwendet wird, gehe ich mal davon aus, das der Fehler nicht da liegt.
Kann mir jemand sagen wo mein Denkfehler ist, bzw. ob es wirklich ein Compiler-Bug ist, daß sich die Speicheradresse der Variable während der Laufzeit verändert?
Ich sitze jetzt schon den 3. Tag an diesem Bug und bin der Verzweiflung nahe :(((
P.S. Gerd konnte mir auch nicht weiterhelfen, er sitzt nur vorm Monitor und sagt kein Wort :|
Ciao, Tobias
Hallo Tobias,
ich glaube lieber erst einmal an einen Programmiererbug... ;-)
Am Samstag, dem 19. Januar 2002 um 15:46:44, schrieb Tobias Koenig:
Klasse_A *ptr = (Klasse_A*)parentWidget();
Versuche hier mal die Vorteile von C++ zwecks statischer Typprüfung zu nutzen:
Klasse_A *ptr = static_cast<Klasse_A*>(parentWidget());
Und
$ c++ -Wold-style-cast ...
hilft auch. Oder schreibe mal ein kleines Testprogramm ohne Qt.
Torsten
On Sun, Jan 20, 2002 at 01:10:08PM +0100, Torsten Werner wrote:
Hallo Tobias,
ich glaube lieber erst einmal an einen Programmiererbug... ;-)
Hoffe ich doch mal, der ließe sich jedenfalls schnell beheben...
Versuche hier mal die Vorteile von C++ zwecks statischer Typprüfung zu nutzen:
Klasse_A *ptr = static_cast<Klasse_A*>(parentWidget());
SensorDisplay.cc:308: static_cast from `QWidget *' to `Klasse_A*' make: *** [SensorDisplay.lo] Error 1
?!? obwohl da ein (QWidget *) zurückgeliefert wird, müsste man doch trotzdem nach einem cast auf die geerbten Methoden/Variablen der Klasse_A zugreifen können oder habe ich da einen Teil von C++ nicht ganz verstanden?!?
Ciao, Tobias
Am Sonntag, dem 20. Januar 2002 um 17:43:11, schrieb Tobias Koenig:
On Sun, Jan 20, 2002 at 01:10:08PM +0100, Torsten Werner wrote:
Klasse_A *ptr = static_cast<Klasse_A*>(parentWidget());
SensorDisplay.cc:308: static_cast from `QWidget *' to `Klasse_A*' make: *** [SensorDisplay.lo] Error 1
Also doch ein Programmiererbug, allerdings bei mir! Natürlich ist ein static_cast von QWidget* nach Klasse_A* nicht möglich.
Klasse_A *ptr = dynamic_cast<Klasse_A*>(parentWidget()); if (!ptr) { // Konvertierung fehlgeschlagen! }
Wichtig ist, dass deine Funktionen auch virtuell sind.
Torsten
lug-dd@mailman.schlittermann.de