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 ?
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.
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;
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.