Czy zostanie wywołany destruktor klasy podstawowej, jeśli obiekt zgłasza wyjątek w konstruktorze?Czy destruktor klasy podstawowej zostanie wywołany, jeśli obiekt zgłasza wyjątek w konstruktorze?
Odpowiedz
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.)
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).
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.
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.
Niezły cytat, ale nie odpowiada na pytanie. – fredoverflow
@FredOverflow, Yeah dzięki ... Zaktualizowano teraz .. :) – liaK
- 1. Czy zostanie automatycznie wywołany konstruktor klasy podstawowej?
- 2. Destruktor nigdy nie zostanie wywołany
- 3. Wyjątek w konstruktorze statycznym
- 4. , który konstruktor klasy String zostanie wywołany, gdy obiekt String zostanie utworzony za pomocą String literal
- 5. Dlaczego obiekt destruktor nie jest wywoływany, gdy skrypt zostanie zakończony?
- 6. Co się stanie, jeśli konstruktor zgłasza wyjątek?
- 7. View.onDraw() --- kiedy zostanie wywołany?
- 8. EKEventViewDelegate didCompleteWithAction nie zostanie wywołany
- 9. testy przestanie działać Jeśli Instalator zgłasza wyjątek w Pythonie unittest
- 10. wyjątek z nie wirtualnym destruktorem C++
- 11. Catching wyjątek w konstruktorze
- 12. Start programu MediaRecorder(), jeśli zostanie wywołany zbyt szybko
- 13. gestureRecognizer: shouldReceiveTouch: nie zostanie wywołany
- 14. SpriteBatch: "Begin nie może zostać wywołany ponownie, dopóki nie zostanie wywołany End."
- 15. Lokalny detektor zdarzeń wywołany, mimo że obiekt nie został skonstruowany
- 16. Utylizacja MemoryCache w Finalizerze zgłasza wyjątek AccessViolationException
- 17. Czy destruktor jest wywoływany podczas rzucania konstruktora delegującego?
- 18. junit.framework.AssertionFailedError: Wyjątek w konstruktorze: (java.lang.NoClassDefFoundError)
- 19. Dlaczego otrzymuję wyjątek StackOverflowError w moim konstruktorze
- 20. Czy powinienem rzucić wyjątek w próbie mutacji niezmiennej klasy? Jeśli tak, jaki wyjątek?
- 21. collectionView: cellForItemAtIndexPath: nigdy nie zostanie wywołany
- 22. Funkcja DialogFragment zgłasza wyjątek ClassCastException, jeśli wywoływana jest z fragmentu
- 23. Używanie "this" w konstruktorze podstawowym?
- 24. destruktor wywołany przed tymczasowym powinien być poza zakresem
- 25. jeśli jest wyjątek w "użyciu" zostanie automatycznie zamknięty
- 26. Czy domyślny destruktor może zostać wygenerowany automatycznie jako destruktor wirtualny?
- 27. Czy SQL SELECT jest szybszy, jeśli zostanie wywołany we właściwej kolejności?
- 28. Android ViewPager's onPageScrollStateChanged nigdy nie zostanie wywołany
- 29. Kompilowanie podstawowej klasy C++
- 30. EclipseLink zgłasza wyjątek ArrayIndexOutOfBoundsException podczas próby przeplatania klasy
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? –
@Steve: Bez haczyka baza nie jest zniszczona podczas mojej implementacji, więc domyślam się, że to nie jest gwarantowane, ale kto wie ...:-) – fredoverflow
Dlatego też dobrym pomysłem jest włożenie haczyka i ponowne wrzucenie do środka, aby zmusić do prawidłowego rozwinięcia stosu. –