Seite 1 von 1

Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem

Verfasst: 08.12.2009, 09:25
von HeinzK
Situations-Skizze:

class ZFEN : public CObject

class SFEN : public ZFEN
class XFEN : public ZFEN

class AFEN : public SFEN

AFEN hat manchmal ein XFEN, aber nicht immer.
AFEN gibt über GetpXFEN() also NULL oder den Zeiger zurück.

Problem:

void ZFEN::Fu(..)
{
...
...
...

XFEN *p = ((AFEN *)this)->GetpXFEN();

if (p != NULL)
{
p->Fu(..)
}
}

Im Debug-Modus ist alles OK.

Hat AFEN ein XFEN wird Fu zweimal aufgerufen!
Hat AFEN kein XFEN dann nur einmal!

Im Release-Modus gibt es ein Problem.

Hat AFEN ein XFEN wird Fu dreimal aufgerufen!
Das dritte Mal sieht so aus, als würde mit new ein neues Objekt angelegt.

Was mir klar ist:

Beim zweiten Aufruf von Fu über p->Fu gibt es natürlich kein AFEN Objekt.
Im Debug-Modus wird dann für p brav NULL zurückgegeben.

Meine Fragen:
Ist das im Debug-Modus Zufall, Glück oder System?
Ist der Ansatz grundsätzlich so nicht möglich?

Hinweis:

Inzwischen habe ich es auf eine andere Weise organisiert.
Die Frage also nur aus Prinzip!

Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem

Verfasst: 08.12.2009, 09:34
von Schrompf
Debug-Symbole anschalten, durchsteppen. Solche Fehler sind in den meisten Fällen auf nicht-initialisierte Variablen und sowas zurückzuführen. Deine Klassenstruktur-Beschreibung habe ich nicht verstanden, aber ich denke, sie ist irrelevant für das Problem.

Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem

Verfasst: 08.12.2009, 09:44
von kimmi
HeinzK hat geschrieben: void ZFEN::Fu(..)
{
...
...
...

XFEN *p = ((AFEN *)this)->GetpXFEN();

if (p != NULL)
{
p->Fu(..)
}
}
Bau in obige Codezeile mal einen dynamic_cast ein. Warum sich nicht zusätzlich noch Hilfe vom Compiler holen?

Gruß Kimmi

Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem

Verfasst: 08.12.2009, 11:52
von Stefan Zerbst
Hi,

wie Schrompf schon sagte sieht es so aus, als ob das Attribut m_xfen in der Klasse AFEN nicht sauber initialisiert ist.

Zudem ist das ein extrem hässliches Design in ZFEN::Fu die Hierarchie runterzucasten um an AFEN::GetXFEN zu kommen. Wenn ZFEN::Fu den Aufruf weiterleiten soll, dann gibt es dafür designtechnisch zwei sinnvolle Lösungen:

1) ZFEN deklariert die Methode GetXFEN virtuell und stellt eine leere Default-Implementierung zur Verfügung die AFEN korrekt überschreibt.

2) AFEN überschreibt das in ZFEN virtuell deklarierte Fu.

Aber ZFEN im Methodenaufruf nach AFEN zu casten ist schon grenzwertig. Und dass ein Objekt als Attribut ein Objekt derselben Klassen-Hierarchie hält schaut auf den ersten Blick auch mal abstrus aus, auch wenn das natürlich auch vom Design her Ok sein kann.

Ciao,
Stefan

Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem

Verfasst: 08.12.2009, 11:54
von Stefan Zerbst
kimmi hat geschrieben:Bau in obige Codezeile mal einen dynamic_cast ein. Warum sich nicht zusätzlich noch Hilfe vom Compiler holen?
Pffffff ... kaum weiß man nicht mehr weiter benutzt man gleich Sprach-Features. Früher wußte man noch was man tat und hat selber nachgedacht anstatt den Compiler die Arbeit machen zu lassen :mrgreen:

[/ironie]

Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem

Verfasst: 08.12.2009, 11:56
von kimmi
Weißte Stefan, das kommt mit dem Alter: Faulheit. Damals kannte ich die Bits noch beim Namen, heute sollen gefälligst andere ( zum Beispiel Compiler ) die Fehler für mich finden :D

Gruß Kimmi

Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem

Verfasst: 08.12.2009, 13:10
von HeinzK
Danke für eure Tipps.
Ich habe nun den Ablauf um einiges besser verstanden.
Die Funktion GetpXFEN muss virtual sein.
Aber, da die Idee im Debug-Modus so einwandfrei funktionierte ..
na .. auf jeden Fall wieder was gelernt!

Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem

Verfasst: 08.12.2009, 14:51
von Stefan Zerbst
HeinzK hat geschrieben:Die Funktion GetpXFEN muss virtual sein.
Ja natürlich :)

Falls dein ursprüngliches Konzept die Methode nicht virtual in mehr als einer Klasse der Hierarchie deklariert hat, dann kann das zu Problemen führen. Namensgleiche Methoden in einer Klasse (selbst bei abweichender Parameterliste) verdecken ganz knallhart namensgleiche Methode in Basis-Klassen. Daher kann es zu unterschiedlichen Ergebnissen führen weil dann der Typ des Zeigers entscheidet, welche Methode aufgerugen wird, und nicht mehr der Typ des Objektes auf den der Zeiger zeigt.

Ciao,
Stefan

Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem

Verfasst: 08.12.2009, 17:00
von kimmi
So etwas führt normalerweise auch zu einer Compilerwarnung, die auf diese Verdeckung einer Methode hinweist. Wenn nicht, einfach das Warning-Level deines Compilers hochstellen, um die Warnung zu erhalten.

Gruß Kimmi

Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem

Verfasst: 08.12.2009, 17:19
von HeinzK
Ich fahre auf Level 3.