Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
- HeinzK
- Establishment
- Beiträge: 234
- Registriert: 05.11.2009, 08:37
- Benutzertext: ZwiAner
- Echter Name: Heinz Kempter
- Wohnort: Wald
- Kontaktdaten:
Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem
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!
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!
Es ist leichter, einen Sack Flöhe zu hüten.
- Schrompf
- Moderator
- Beiträge: 4869
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas Ziegenhagen
- Wohnort: Dresden
- Kontaktdaten:
Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem
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.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
- kimmi
- Moderator
- Beiträge: 1405
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem
Bau in obige Codezeile mal einen dynamic_cast ein. Warum sich nicht zusätzlich noch Hilfe vom Compiler holen?HeinzK hat geschrieben: void ZFEN::Fu(..)
{
...
...
...
XFEN *p = ((AFEN *)this)->GetpXFEN();
if (p != NULL)
{
p->Fu(..)
}
}
Gruß Kimmi
-
- Moderator
- Beiträge: 189
- Registriert: 25.02.2009, 19:54
Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem
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
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
-
- Moderator
- Beiträge: 189
- Registriert: 25.02.2009, 19:54
Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem
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:kimmi hat geschrieben:Bau in obige Codezeile mal einen dynamic_cast ein. Warum sich nicht zusätzlich noch Hilfe vom Compiler holen?
[/ironie]
- kimmi
- Moderator
- Beiträge: 1405
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem
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
Gruß Kimmi
- HeinzK
- Establishment
- Beiträge: 234
- Registriert: 05.11.2009, 08:37
- Benutzertext: ZwiAner
- Echter Name: Heinz Kempter
- Wohnort: Wald
- Kontaktdaten:
Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem
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!
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!
Es ist leichter, einen Sack Flöhe zu hüten.
-
- Moderator
- Beiträge: 189
- Registriert: 25.02.2009, 19:54
Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem
Ja natürlich :)HeinzK hat geschrieben:Die Funktion GetpXFEN muss virtual sein.
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
- kimmi
- Moderator
- Beiträge: 1405
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem
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
Gruß Kimmi
- HeinzK
- Establishment
- Beiträge: 234
- Registriert: 05.11.2009, 08:37
- Benutzertext: ZwiAner
- Echter Name: Heinz Kempter
- Wohnort: Wald
- Kontaktdaten:
Re: Vererbung: Vater ruft Enkel .. Debug: OK .. Release: Problem
Ich fahre auf Level 3.
Es ist leichter, einen Sack Flöhe zu hüten.