Wyjątek w konstruktorze

0

Co się dzieje z obiektem, gdy w jego konstruktorze wystąpi wyjątek ? Czy zarezerwowana pamięć na obiekt zostaje zwolniona (i co z obiektami które powstały w klasie pierwotnej ?), czy może jest automatycznie zwalniana ?

0

Wszystko co zarezerwowałeś ręcznie powinieneś jeszcze w konstruktorze (try finally end) zwolnić, natomiast puszczenie obsługi wyjątku poziom wyżej powoduje, że część automatyczna tworzenia obiektu posprząta co stworzyła. Przykład:

constructor TKlasa.Create();
begin
try
  //Alokacja1
  //Wyjątek1
except
  end;
//Dealokacja1
try
  //Alokacja2
  //Wyjątek2
finally
  //Dealokacja2
  end
end;

Jeśli wystąpi Wyjątek1, nastąpi Dealokacja1, bo blok zakończy się zatrzymaniem wyjątku na except. Jeśli dalej nie wystąpi Wyjątek2, obiekt zostanie utworzony (Obiekt:=TKlasa.Create(); zwróci pod zmienną Obiekt właściwie utworzony obiekt).

Jeśli nie wystąpi Wyjątek1, a wystąpi Wyjątek2, nastąpi Dealokacja2 (bo w bloku finally), a obiekt nie zostanie utworzony (Obiekt:=TKlasa.Create(); zwróci pod zmienną Obiekt wartość nil).

Kod:

constructor TKlasa.Create();
begin
//Alokacja1
//Wyjątek1
//Dealokacja1
end;

pozostawiłby śmieci w pamięci po Alokacja1, bo Wyjątek1 spowoduje przeskoczenie do końca procedury bez wywołania Dealokacja1, a i tak obiekt nie zostanie utworzony (konstruktor zwróci nil).

Wniosek: jeśli coś alokujesz w konstruktorze, to zadbaj, aby - przy niepowodzeniu konstruktora - jeszcze w nim zostało zdealokowane.

0
Pytający napisał(a)

Co się dzieje z obiektem, gdy w jego konstruktorze wystąpi wyjątek ? Czy zarezerwowana pamięć na obiekt zostaje zwolniona (i co z obiektami które powstały w klasie pierwotnej ?), czy może jest automatycznie zwalniana ?

Sterowanie przejdzie do destruktora - wniosek, to co alokujesz w kontruktorze, zwalniaj w destruktorze.

To samo się tyczy klas pierwotnych, zawsze w kontruktorze klas pochodnych wywołuj najpierw:
inherited Create a w destruktorze NA KOŃCU inderited Destroy;

0

Tak, zapomniałem dodać (bo w ogóle zapomniałem), że przed zwróceniem wyniku konstruktora wywoływany jest jeszcze destruktor przy wystąpieniu wyjątku.

b0bik ma rację w tym względzie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1