Verhalten von Destruktoren



  • Moin,

    ich habe momentan zwei Fragen zum Verhalten von Destruktoren:

    class A
    {
    public:
    ~A(); // Nichttrivialer Destruktor
    std::string foo;
    }

    In diesem Fall ist es problemlos möglich (und somit definiertes Verhalten) auf foo innerhalb vom Destruktor ~A zuzugreifen, richtig?

    class A
    {
    public:
    virtual ~A();
    }

    class B : public A
    {
    public:
    ~B(); // Nichttrivialer Destruktor
    }

    class C
    {
    public:
    ~C(); // Nichttrivialer Destruktor
    }

    class D : public B, public C
    {
    public:
    ~D();
    }

    Wenn jetzt eine Instanz von D zerstört wird, wird dann auch der virtuelle Destruktor von A aufgerufen?



  • Hoppala, code Tags verpennt, Sorry!

    class A
    {
    public:
    ~A(); // Nichttrivialer Destruktor
    std::string foo;
    }
    
    class A
    {
    public:
    virtual ~A();
    }
    
    class B : public A
    {
    public:
    ~B(); // Nichttrivialer Destruktor
    }
    
    class C
    {
    public:
    ~C(); // Nichttrivialer Destruktor
    }
    
    class D : public B, public C
    {
    public:
    ~D();
    }
    

  • Mod

    z1) Es ist immer möglich auf die Member einer Klasse innerhalb des Destruktors zuzugreifen. Vorsicht ist lediglich bei virtuellen Memberfunktionen geboten: falls diese in einer abgeleiteten Klasse überschrieben wurden, ist diese Überschreibung im Destruktor nicht mehr aktiv (weil der abgeleitete Teil des Objektes bereits zerstört wurde) sondern diejenige Überschreibung, die für die Klasse, deren Destruktor gerade läuft, gerade gültig ist. Falls keine solche Überschreibung existiert (rein virtuelle Funktion ohne Definition) resultiert undefiniertes Verhalten, für gewöhnlich in Form einer Nullzeigerderefernzierung.

    1. Nachdem der Funktionskörper des Destruktors einer Klasse verlassen wurde, werden die Destruktoren aller Member und (direkten) Basisklassen in umgekehrter Reihenfolge Ihrer Konstruktion aufgerufen (indirekt geerbte virtuelle Basisklassen werden für diesen Zweck wie direkte Basisklassen betrachtet, so wie es auch beim Ablauf des Konstruktors der Fall ist).

    Nach Ablauf von D::~D wird also zunächst C::~C und dann B::~B aufgerufen und schließlich läuft A::~A (als direkte Basis von B).


Log in to reply