Wyjątki: konwertowanie z makr wyjątków MFC
Jest to zaawansowany temat.
W tym artykule wyjaśniono, jak przekonwertować istniejący kod napisany za pomocą makr klasy programu Microsoft Foundation — TRY, CATCH, THROW itd. — w celu użycia słów kluczowych try
obsługi wyjątków języka C++ , catch
i throw
. Tematy obejmują:
Zalety konwersji
Prawdopodobnie nie trzeba konwertować istniejącego kodu, chociaż należy pamiętać o różnicach między implementacjami makr w MFC w wersji 3.0 i implementacjami we wcześniejszych wersjach. Te różnice i kolejne zmiany zachowania kodu zostały omówione w artykule Wyjątki: zmiany w makrach wyjątków w wersji 3.0.
Główne zalety konwersji to:
Kod, który używa słów kluczowych obsługi wyjątków języka C++ kompiluje się do nieco mniejszego pliku .EXE lub biblioteki DLL.
Słowa kluczowe obsługi wyjątków języka C++ są bardziej uniwersalne: mogą obsługiwać wyjątki dowolnego typu danych, które można skopiować (
int
,float
,char
i tak dalej), podczas gdy makra obsługują wyjątki tylko klasCException
i klas pochodnych.
Główną różnicą między makrami a słowami kluczowymi jest to, że kod korzystający z makr "automatycznie" usuwa wyjątek przechwycony, gdy wyjątek wykracza poza zakres. Kod używający słów kluczowych nie, dlatego należy jawnie usunąć przechwycony wyjątek. Aby uzyskać więcej informacji, zobacz artykuł Wyjątki: przechwytywanie i usuwanie wyjątków.
Inną różnicą jest składnia. Składnia makr i słów kluczowych różni się pod trzema względami:
Argumenty makr i deklaracje wyjątków:
Wywołanie makr CATCH ma następującą składnię:
CATCH(exception_class, exception_object_pointer_name)
Zwróć uwagę na przecinek między nazwą klasy a nazwą wskaźnika obiektu.
Deklaracja wyjątku dla słowa kluczowego
catch
używa tej składni:catch(exception_type exception_name)
Ta instrukcja deklaracji wyjątku wskazuje typ wyjątku dojścia bloku catch.
Ogranicznik bloków catch:
W makrach makro CATCH (z jego argumentami) rozpoczyna pierwszy blok catch; makro AND_CATCH rozpoczyna kolejne bloki catch, a makro END_CATCH kończy sekwencję bloków catch.
Ze słowami kluczowymi
catch
słowo kluczowe (z deklaracją wyjątku) rozpoczyna każdy blok catch. Nie ma odpowiednika makra END_CATCH ; blok catch kończy się nawiasem klamrowym zamykającym.Wyrażenie throw:
Makra używają THROW_LAST , aby ponownie zgłosić bieżący wyjątek. Słowo
throw
kluczowe bez argumentu ma taki sam efekt.
Wykonywanie konwersji
Aby przekonwertować kod przy użyciu makr, aby użyć słów kluczowych obsługi wyjątków języka C++
Znajdź wszystkie wystąpienia makr MFC TRY, CATCH, AND_CATCH, END_CATCH, THROW i THROW_LAST.
Zastąp lub usuń wszystkie wystąpienia następujących makr:
TRY (Zastąp ją ciągiem
try
)CATCH (zastąp go ciągiem
catch
)AND_CATCH (zastąp ją ciągiem
catch
)END_CATCH (usuń je)
THROW (Zamień go na
throw
)THROW_LAST (zastąp ją ciągiem
throw
)Zmodyfikuj argumenty makr, tak aby tworzyły prawidłowe deklaracje wyjątków.
Na przykład zmień
CATCH(CException, e)
na wartość
catch (CException* e)
Zmodyfikuj kod w blokach catch, aby w razie potrzeby usuwał obiekty wyjątków. Aby uzyskać więcej informacji, zobacz artykuł Wyjątki: przechwytywanie i usuwanie wyjątków.
Oto przykład kodu obsługi wyjątków przy użyciu makr wyjątków MFC. Należy pamiętać, że ponieważ kod w poniższym przykładzie używa makr, wyjątek e
jest usuwany automatycznie:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e)
{
if (m_bPassExceptionsUp)
THROW_LAST();
if (m_bReturnFromThisFunction)
return;
// Not necessary to delete the exception e.
}
END_CATCH
Kod w następnym przykładzie używa słów kluczowych wyjątków języka C++, dlatego należy jawnie usunąć wyjątek:
try
{
// Do something to throw an exception.
AfxThrowUserException();
}
catch (CException* e)
{
if (m_bPassExceptionsUp)
throw;
if (m_bThrowDifferentException)
{
e->Delete();
throw new CMyOtherException;
}
if (m_bReturnFromThisFunction)
{
e->Delete();
return;
}
e->Delete();
}
Aby uzyskać więcej informacji, zobacz Wyjątki: używanie makr MFC i wyjątków języka C++.