Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Chase

Alter Hase

  • »Chase« ist der Autor dieses Themas

Beiträge: 753

Wohnort: Nagaoka / Darmstadt / Düsseldorf

Beruf: fauler Studi

  • Private Nachricht senden

1

03.08.2006, 13:42

Parent destructor

Ich habe fast die gleiche Frage schon mal gestellt, aber ich kriegs immer noch nicht hin:
Wie ruf ich den Destruktor der Base-Klasse auf?

Beim Konstruktor hab ich keine Probleme, da geht das per Initialisierungsliste

C-/C++-Quelltext

1
   Derived::Derived() : Base()  //wird sowieso so kompiliert

aber wenn ich das mit dem Destructor so machen will, gibts logischerweise einen Syntax-Error, ein Destructor hat schliesslich garkeine Initialisierungsliste.
"Have you tried turning it off and on again?"

Black-Panther

Alter Hase

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

2

03.08.2006, 13:55

hmmm.. ich glaub doch, dass der Destruktor automatisch aufgerufen wird? oder?
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

3

03.08.2006, 14:05

Ja, der wird automatisch aufgerufen.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cstdio>

class A
{
public:
    A() { printf("A::A\n"); }
    ~A() { printf("A::~A\n"); }
};

class B : public A
{
public:
    B() { printf("B::B\n"); }
    ~B() { printf("B::~B\n"); }
};

int main()
{
    B test;
    return 0;
}


Am Ende (nachdem "test" zerstört wurde), sollte die Ausgabe lauten:

Quellcode

1
2
3
4
A::A
B::B
B::~B
A::~A


Wenn du mit Zeigern auf Basisklasseninstanzen arbeitest, musst du den Destruktor virtual deklarieren. Das hier wäre nicht korrekt:

C-/C++-Quelltext

1
2
A* p_meinObjekt = new B;
delete p_meinObjekt;


Dann würde nur der Destruktor von A aufgerufen, aber nicht der von B.
Damit das so klappt, musst du den Destruktor virtuell machen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
class A
{
public:
    A() { printf("A::A\n"); }
    virtual ~A() { printf("A::~A\n"); }
};

class B : public A
{
public:
    B() { printf("B::B\n"); }
    ~B() { printf("B::~B\n"); }
};


Der von B muss nicht virtuell sein, solange du keine weiteren Klassen mehr von B ableitest.

Chase

Alter Hase

  • »Chase« ist der Autor dieses Themas

Beiträge: 753

Wohnort: Nagaoka / Darmstadt / Düsseldorf

Beruf: fauler Studi

  • Private Nachricht senden

4

03.08.2006, 14:25

ich arbeite mit Zeigern auf die Basisklasse und der Destruktor ist auch virtuell. Aber der Parent-Destruktor scheint bei mir nicht aufgerufen zu werden. Hab das mal so ueberprueft:

C-/C++-Quelltext

1
2
3
4
5
 Base::~Base()
{
  if(dynamic_cast<Derived*>(this))
     MessageBox(0,"parent destructor called","info",0);
}

Aber die Nachricht erscheint nie.

Edit: Habs jetzt noch mal anders ueberprueft. Es ist tatsaechlich so, dass der dynamic_cast innerhalb der Basisklasse nicht richtig funktioniert. Wahrscheinlich weil der this-Zeiger dann schon auf Base* gecastet wurde
"Have you tried turning it off and on again?"

Black-Panther

Alter Hase

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

5

03.08.2006, 15:02

btw: Das müsste doch mit static_cast funktionieren, oder?
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

6

03.08.2006, 18:00

Nein, mit static_cast wäre die if-Abfrage immer true (wenn der Compiler nicht schon meckert), weil der this-Zeiger zu diesem Zeitpunkt nicht NULL ist und ein static_cast daran nichts ändert.

static_cast ist ein Gegenstück zum Ordinären C-Cast (mit ein paar weiteren Typ-Checks). dynamic_cast liefert 0, wenn der übergebene Zeiger nicht vom richtigen Typ ist, d.h. wenn das konkrete Objekt nicht selbst ein Objekt der angegebenen Klasse oder davon abgeleitet ist.

Der dynamic_cast im Destructor wird hier immer false liefern, weil der Destructor der abgeleiteten Klasse bereits gelaufen ist, und das Objekt selbst damit quasi schon nicht mehr vom Typ der abgeleiteten Klasse ist.

So wie David das beschrieben hat, ist das schon gut so.

MfG,
Rainer

PS: das echte Gegenstück zum C-Cast ist natürlich reinterpret_cast.

PPS: wer oft dynamic_cast benutzt, macht prinzipiell schonmal was falsch. ;)
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Black-Panther

Alter Hase

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

7

03.08.2006, 19:21

sry... sollte genauer hinschaun... hab nicht auf die if geschaut :roll: :roll:
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

Anonymous

unregistriert

8

03.08.2006, 19:24

Chase
Der Parentdestructor wird bei baumähnlichen Vererbungen immer aufgerufen, wenn Du Netz-Vererbungen betreibst, sieht die Sache anders aus.

Ob Dein Destructor nun virtual ist oder nicht, ist in diesem Fall absolut Schnuppe.

Werbeanzeige