Co to jest dobry sposób w C++, aby wykryć w destruktorze, że jest uruchamiany podczas rozwijania stosu z powodu wyrzucanego wyjątku, w przeciwieństwie do normalnego wyjścia z zakresu wyzwalającego destruktor? Chciałbym wiedzieć, żebym mógł utworzyć klasę, która ma jakiś kod czyszczenia, który jest zawsze uruchamiany przy normalnym wyjściu, ale pomijany, gdy wystąpi wyjątek.Wykrywanie, kiedy destruktor działa z powodu odrzucenia wyjątku?
Odpowiedz
std::uncaught_exception()
(zdefiniowane w <exception>
) powie Ci w destructor gdyby był nazywany ze względu na wyjątek:
class A
{
public:
~A()
{
if (std::uncaught_exception()) {
// Called because of an exception
} else {
// No exception
}
}
};
Miło, nigdy nie wiedziałem, że to istnieje! :-) –
Nie tak miło, jak mogłoby się wydawać - zobacz połączony artykuł na moim poście. – Simon
Oto jeden sposób mogę myśleć, ale wydaje się niezgrabny:
{
myCleanupClass unwindAction;
try {
// do some work which may throw exception.
} catch (...) {
unwindAction.disableDestructorWork();
throw;
}
}
Nie rób tego, chyba że masz dobry powód. Rozwijanie stosów jest taką funkcją językową, że wszystkie automatyczne obiekty w bloku try
zostaną wymuszone, aby zwolnić zasoby, tak aby zasoby wewnątrz nich mogły zostać uwolnione.
Chcesz pominąć czyszczenie w dtor podczas rozwijania stosu, które omija pierwotną intencję. I będziesz narażony na ryzyko przeciekania zasobów.
Przykład
class CDBConnection
{
public:
CDBConnection()
{
m_db.open();
}
~CDBConnection()
{
if (!std::uncaught_exception())
m_db.close();
// if this is called during a stack unwinding,
// your DB connection will not be closed for sure.
// That's a resource leakage.
}
//..
private:
DB m_db;
};
void main()
{
//..
try
{
// code that may throw
CDBConnection db;
//..
}
catch(const CDBException& exp)
{
// properly handle the exception
}
}
Prawdopodobnie this artykuł pomoże. Artykuł pokaże Ci problemy ze std :: uncaught_exception() i zawiera porady dotyczące radzenia sobie z wyjątkami w destruktorach.
- 1. Jak znaleźć przyczynę odrzucenia wyjątku EETypeLoadException?
- 2. Android TestRunner nie z powodu wyjątku IllegalState
- 3. Wykrywanie wyjątku OutOfMemoryException podczas szeregowania z JSON?
- 4. Kiedy należy pozwolić aplikacji na awarię z powodu wyjątku w języku Java (problem z projektowaniem)?
- 5. Gdzie działa UIAlertView na żywo bez odrzucenia
- 6. Wykrywanie kiedy ValueAnimator odbywa
- 7. iOS 7: UIWebView ulega awarii z powodu wyjątku zakresu
- 8. Kiedy używać nowego wyjątku typu:
- 9. Phpldapadmin nie działa z nieznanego powodu.
- 10. Wykrywanie uiscrollview nie jest przewijane z powodu autolayout
- 11. Android: Wykrywanie Kiedy Scrollview Odsłon dno
- 12. Kończenie aplikacji z powodu nieprzechwyconego wyjątku "Nie znaleziono Atlas tekstury"
- 13. Testy jednostek debugowania, które zawiodły z powodu wyjątku StackOverflow
- 14. Wykrywanie zmian tekstu UITextField z powodu cofnięcia Shake'a?
- 15. Python: wykrywanie, gdy gniazdo zostanie odłączone z jakiegokolwiek powodu?
- 16. PDFKIT najwyraźniej nie działa z powodu "wkhtmltopdf"
- 17. jcvl nie działa z powodu wymagań jcl
- 18. GRUPA CONCAT nie działa z jakiegoś powodu
- 19. Wykrywanie przeciągnij i upuść + wykrywanie nie działa
- 20. Destruktor drzewa wyszukiwania binarnego
- 21. Alert użytkownik, kiedy uderzył w przeglądarce przycisk Wstecz - z powodu
- 22. Nieobsługiwane zdarzenie wyjątku nie działa?
- 23. wykrywanie, kiedy mailto nie powiodło się
- 24. Mobile Web: Wykrywanie kiedy zdjęcia zostały wyłączone
- 25. Jak działa kod po wyjątku?
- 26. Kątowe - wykrywanie, kiedy kontroler jest "wyładowany"
- 27. Leaflet.js: wykrywanie kiedy mapa kończy powiększanie
- 28. Wykrywanie kiedy mysz się nie porusza
- 29. Wyjątek JsonSyntaxException z powodu IllegalState of gson
- 30. Visual Studio działa zbyt wolno z Angular2 z powodu node_modules
Interesujące pytanie! Kusi mnie, aby powiedzieć, że nie da się tego zrobić, ponieważ obiekty tak naprawdę nie wiedzą o tym, że wyjątek jest aktywny, po prostu wychodzą poza zakres, ponieważ wyjątek rozwija stos, tak jak gdyby wypadł z jakiegokolwiek innego zakres. Jeśli potrzebujesz czegoś konkretnego "hacka" dla platformy ... –
Ciekawe, dlaczego chcesz uniknąć czyszczenia podczas rozwijania stosu? –
@Eric Z: Pomyślałem, że użyję tego do automatycznego rejestrowania 'stack'. Coś w stylu 'Log xxx (" funcA - ", arg1, arg2, arg3);', ale oprzyrządowanie funkcji jest nużące. –