2010-09-21 7 views

Odpowiedz

15

Jeśli podczas budowy zostanie rzucony wyjątek, wszystkie wcześniej utworzone pod-obiekty zostaną odpowiednio zniszczone. Poniższy program pokazuje, że podstawa jest zdecydowanie zniszczone:

struct Base 
{ 
    ~Base() 
    { 
     std::cout << "destroying base\n"; 
    } 
}; 

struct Derived : Base 
{ 
    Derived() 
    { 
     std::cout << "throwing in derived constructor\n"; 
     throw "ooops..."; 
    } 
}; 

int main() 
{ 
    try 
    { 
     Derived x; 
    } 
    catch (...) 
    { 
     throw; 
    } 
} 

wyjściowa:

throwing in derived constructor 
destroying base 

(Zauważ, że destruktor native wskaźnik nic nie robi, dlatego wolimy RAII nad surowych wskaźników.)

+1

Nie pamiętam - jeśli nie przechwyciłeś wyjątku, czy destruktor klasy bazowej jest gwarantowany do wywołania, czy też jest liczony jako część "rozwijania stosu" i dlatego jest zdefiniowany przez implementację, czy występuje czy nie na nieprzechwycony wyjątek? –

+0

@Steve: Bez haczyka baza nie jest zniszczona podczas mojej implementacji, więc domyślam się, że to nie jest gwarantowane, ale kto wie ...:-) – fredoverflow

+3

Dlatego też dobrym pomysłem jest włożenie haczyka i ponowne wrzucenie do środka, aby zmusić do prawidłowego rozwinięcia stosu. –

9

Tak. Zasadą jest, że każdy obiekt, którego konstruktor zakończył się pomyślnie, zostanie zniszczony podczas wyjątku. Np .:

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

class B : public A { 
public: 
    B() { throw 0; } 
    ~B() {} 
}; 

~ Zostaje wywołana funkcja A(). ~ B() nie jest wywoływane;

EDIT: Poza tym, że masz członków:

struct A { 
    A(bool t) { if(t) throw 0; } 
    ~A() {} 
}; 

struct B { 
    A x, y, z; 
    B() : x(false), y(true), z(false) {} 
}; 

Co się dzieje: x jest skonstruowany, y wyrzuca, x jest zniszczona (ale ani y ani z).

5

Kiedy wyjątek jest, że destruktory nazywane dla Wszystkie (pod) przedmioty, których konstruktorzy udało się uruchomić. Dotyczy to zarówno elementów danych, jak i klas bazowych.

Na przykład tego kodu

struct base {}; 

struct good {}; 

struct bad { 
    bad() {throw "frxgl!";} 
}; 

struct test : public base { 
    std::string s; 
    good g; 
    bad b; 
    test() {} 
}; 

przed konstruktora test jest wykonywana jest najpierw konstruktor klasy bazowej jest wywoływana, a następnie przez konstruktorów dla s, g i b. Dopiero po pomyślnym zakończeniu zostanie wykonany konstruktor dla test. Kiedy wyjątek jest generowany podczas konstrukcji b, konstruktory klasy podstawowej, a także konstruktory dla elementu danych s i g zostały w pełni wykonane, więc ich destruktory są uruchamiane. Sam konstruktor klasy test i b nie został pomyślnie uruchomiony, więc ich destruktory nie są uruchamiane.

4

z Standard Dokumentach 15,3 - 11,

W wykończona klasy bazowe i członkowie obiektu są niszczone przed wejściem do obsługi przez funkcję try- blokowy lub konstruktora destruktor dla tego obiektu.

+1

Niezły cytat, ale nie odpowiada na pytanie. – fredoverflow

+0

@FredOverflow, Yeah dzięki ... Zaktualizowano teraz .. :) – liaK

Powiązane problemy