Wyjątki: Zmiany w makrach wyjątku, w wersji 3.0
Jest to temat zaawansowany.
W MFC wersja 3.0 i nowsze zmieniono makra obsługi wyjątków użyć wyjątki C++.Tym artykule wyjaśniono, jak te zmiany mogą wpływać na zachowanie istniejącego kodu makra.
W tym artykule omówiono następujące tematy:
Typy wyjątków i makra połowów
Wyjątki RE-throwing
Typy wyjątków i makra połowów
We wcześniejszych wersjach MFC połowu makro używany MFC run-time, wpisz informacje w celu określenia typu wyjątku; Typ wyjątku ustalona, innymi słowy, w witrynie połowu.Wyjątków C++ typu wyjątku jest jednak zawsze określona w witrynie throw przez typ obiektu wyjątek, który jest generowany.Spowoduje to niezgodności w rzadkich przypadkach, gdy typ wskaźnika do obiektu thrown różni się od typu obiektu thrown.
Poniższy przykład ilustruje konsekwencją tej różnicy między MFC w wersji 3.0 i starszych wersjach:
TRY
{
THROW( (CException*) new CCustomException() );
}
CATCH( CCustomException, e )
{
TRACE( "MFC 2.x will land here\n" );
}
AND_CATCH( CException, e )
{
TRACE( "MFC 3.0 will land here\n" );
}
END_CATCH
Kod ten zachowuje się inaczej w wersji 3.0, ponieważ formant zawsze przechodzi do pierwszej połowu blok z pasującą deklarację wyjątek.Wynik wyrażenia rzut
THROW( (CException*) new CCustomException() );
zostanie zgłoszony jako CException *, mimo że jest skonstruowany jako CCustomException.Połowu makro w MFC wersji 2.5 i wcześniejszych zastosowań CObject::IsKindOf do testowania typu w czasie wykonywania.Ponieważ wyrażenie
e->IsKindOf(RUNTIME_CLASS(CException));
prawdą jest, pierwszy blok catch przechwytuje wyjątek.W wersji 3.0, która używa wyjątki C++ do wykonania wielu makr obsługi wyjątków, drugi blok catch odpowiada thrown CException.
Kod, jak to jest mało prawdopodobna.Zwykle wyświetlane, gdy obiekt wyjątku jest przekazywana do innej funkcji, która akceptuje rodzajowego CException *, wykonuje przetwarzanie "pre-throw" i ostatecznie generuje wyjątek.
Aby obejść ten problem, przenieść wyrażenie throw z funkcji kod wywołujący i Zgłoś wyjątek rzeczywisty typ znane w chwili wyjątek jest generowany w kompilatorze.
Wyjątki re-Throwing
Blok catch nie można zgłosić wskaźnik wyjątek złowionych go.
Na przykład ten kod był ważny w poprzednich wersjach, ale będzie nieoczekiwane wyniki w wersji 3.0:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH( CException, e )
{
THROW( e ); // Wrong. Use THROW_LAST() instead
}
END_CATCH
}
Za pomocą THROW w połowu bloku powoduje wskaźnika e do usunięcia, tak aby witryny zewnętrznej połowu otrzymają wskaźnika.Use THROW_LAST to re-throw e.
Aby uzyskać więcej informacji, zobacz wyjątki: połowu i usuwanie wyjątki.