Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym artykule omówiono zagadnienia dotyczące pisania kodu, który korzysta zarówno z makr obsługi wyjątków MFC, jak i słów kluczowych obsługi wyjątków języka C++.
W tym artykule opisano następujące tematy:
Mieszanie słów kluczowych i makr wyjątków
W tym samym programie można mieszać makra wyjątków MFC i słowa kluczowe wyjątków języka C++. Nie można jednak mieszać makr MFC ze słowami kluczowymi wyjątków języka C++ w tym samym bloku, ponieważ makra automatycznie usuwają obiekty wyjątków po opuszczeniu zasięgu, podczas gdy kod używający słów kluczowych obsługi wyjątków tego nie robi. Aby uzyskać więcej informacji, zobacz artykuł Wyjątki: przechwytywanie i usuwanie wyjątków.
Główną różnicą między makrami a słowami kluczowymi jest to, że makra "automatycznie" usuwają przechwycony wyjątek, gdy wyjątek wykracza poza zakres. Kod wykorzystujący słowa kluczowe nie działa; wyjątki przechwycone w bloku catch muszą zostać jawnie usunięte. Mieszanie makr i słów kluczowych wyjątków języka C++ może spowodować przecieki pamięci, gdy obiekt wyjątku nie zostanie usunięty lub uszkodzenie sterty, gdy wyjątek zostanie usunięty dwukrotnie.
Poniższy kod, na przykład, unieważnia wskaźnik wyjątku:
TRY
{
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e) // The "inner" catch block
{
throw; // Invalid attempt to throw exception
// to the outer catch block below.
}
END_CATCH
}
CATCH(CException, e) // The "outer" catch block
{
// Pointer e is invalid because
// it was deleted in the inner catch block.
}
END_CATCH
Problem występuje, ponieważ e jest usuwany, gdy wykonanie opuszcza "wewnętrzny" blok CATCH. Użycie makra THROW_LAST zamiast instrukcji THROW spowoduje, że blok "outer" CATCH otrzyma prawidłowy wskaźnik:
TRY
{
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e) // The "inner" catch block
{
THROW_LAST(); // Throw exception to the outer catch block below.
}
END_CATCH
}
CATCH(CException, e) // The "outer" catch block
{
// Pointer e is valid because
// THROW_LAST() was used.
}
END_CATCH
Bloki try wewnątrz bloków catch
Nie można ponownie zgłosić bieżącego wyjątku z bloku try, który znajduje się wewnątrz bloku CATCH. Poniższy przykład jest nieprawidłowy:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e)
{
try
{
throw; // Wrong. Causes e (the exception
// being thrown) to be deleted.
}
catch (CException* exception)
{
exception->ReportError();
}
}
END_CATCH
Aby uzyskać więcej informacji, zobacz Wyjątki: badanie zawartości wyjątku.