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

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Antworten
Benutzeravatar
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

Beitrag 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!
Es ist leichter, einen Sack Flöhe zu hüten.
Benutzeravatar
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

Beitrag 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.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
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

Beitrag 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
Stefan Zerbst
Moderator
Beiträge: 189
Registriert: 25.02.2009, 19:54

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

Beitrag 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
Stefan Zerbst
Moderator
Beiträge: 189
Registriert: 25.02.2009, 19:54

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

Beitrag 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]
Benutzeravatar
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

Beitrag 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
Benutzeravatar
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

Beitrag 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!
Es ist leichter, einen Sack Flöhe zu hüten.
Stefan Zerbst
Moderator
Beiträge: 189
Registriert: 25.02.2009, 19:54

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

Beitrag 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
Benutzeravatar
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

Beitrag 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
Benutzeravatar
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

Beitrag von HeinzK »

Ich fahre auf Level 3.
Es ist leichter, einen Sack Flöhe zu hüten.
Antworten