Instrukcje try, throw i catch (C++)
Aby zaimplementować obsługę wyjątków w języku C++, należy użyć wyrażeń try, throw i catch.
Najpierw za pomocą bloku try obejmij jedną lub więcej instrukcji, które mogą zgłosić wyjątek.
Wyrażenie throw informuje, że wyjątkowy warunek — zazwyczaj błąd — wystąpił w bloku try.Można użyć dowolnego typu obiektu jako operandu wyrażenia throw wyrażenie.Obiekt ten jest zazwyczaj używany do przekazywania informacji o błędzie.W większości przypadków zaleca się użycie klasy std::exception lub jednej z klas pochodnych, które są zdefiniowane w bibliotece standardowej.Jeżeli jedna z nich nie jest właściwa, firma Microsoft zaleca wyprowadzenie własnej klasy pochodnej do obsługi wyjątków z std::exception.
Do obsługi wyjątków, które mogą być generowane, zaimplementuj jeden lub więcej bloków catch zaraz po bloku try.Każdy blok catch określa typ wyjątku, który może obsługiwać.
W tym przykładzie przedstawiono blok try i jego obsługę.Załóżmy, że GetNetworkResource() uzyskuje dane poprzez połączenie sieciowe i że dwa typy wyjątków to klasy zdefiniowane przez użytkownika, pochodne z std::exception.Należy zauważyć, że wyjątki są przechwytywane przez odwołanie const w instrukcji catch.Firma Microsoft zaleca, aby generować wyjątki przez wartość i przechwytywać przez odniesienie const.
Przykład
MyData md;
try {
// Code that could throw an exception
md = GetNetworkResource();
}
catch (const networkIOException& e) {
// Code that executes when an exception of type
// networkIOException is thrown in the try block
// ...
// Log error message in the exception object
cerr << e.what();
}
catch (const myDataFormatException& e) {
// Code that handles another exception type
// ...
cerr << e.what();
}
// The following syntax shows a throw expression
MyData GetNetworkResource()
{
// ...
if (IOSuccess == false)
throw networkIOException("Unable to connect");
// ...
if (readError)
throw myDataFormatException("Format error");
// ...
}
Uwagi
Kod po klauzuli try to zabezpieczona sekcja kodu.Wyrażenie throwzgłasza — czyli generuje — wyjątek.Blok kodu po klauzuli catch to obsługa wyjątku.Jest to blok obsługi, który przechwytuje zgłoszony wyjątek, jeśli typy w wyrażeniach throw i catch są zgodne.Aby uzyskać listę reguł, które określają dopasowanie typu w blokach catch, zobacz Sposób oceniania bloków Catch (C++).Jeśli instrukcja catch określa wielokropek (...), a nie typ, blok catch obsługuje każdy typ wyjątku.Przy kompilacji z opcją /EHa, mogą to być wyjątki strukturalne C oraz wyjątki asynchroniczne wygenerowane przez system lub aplikację, takie jak naruszenie ochrony pamięci, dzielenie przez zero i błędy liczb zmiennopozycyjnych.Ponieważ bloki catch są przetwarzane w kolejności programu w celu znalezienia pasującego typu, kod obsługi wielokropka musi być ostatnim kodem obsługi skojarzonego z nim bloku try.Używaj catch(...) z ostrożnością; nie zezwalaj programowi na kontynuację, chyba że blok catch wie, jak obsłużyć określony przechwycony wyjątek.Zazwyczaj blok catch(...) jest używany do rejestracji błędów i wykonywania specjalnej operacji czyszczenia, zanim wykonywanie programu zostanie zatrzymane.
Wyrażenie throw, które ma nie operandu, ponownie zgłasza aktualnie obsługiwany wyjątek.Zaleca się tę formę podczas ponownego zgłaszania wyjątku, ponieważ pozwala to zachować informacje o polimorficznym typie oryginalnego wyjątku.Takiego wyrażenia powinno się używać tylko w kodzie obsługi catch lub w funkcji, która jest wywoływana z kodu obsługi catch.Ponownie zgłoszony obiekt wyjątku to oryginalny obiekt wyjątku, a nie kopia.
try {
throw CSomeOtherException();
}
catch(...) {
// Catch all exceptions – dangerous!!!
// Respond (perhaps only partially) to the exception, then
// re-throw to pass the exception to some other handler
// ...
throw;
}