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 tryobsługi wyjątków języka C++ , catchi 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, chari tak dalej), podczas gdy makra obsługują wyjątki tylko klas CException 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:

  1. 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.

  2. 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.

  3. 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++

  1. Znajdź wszystkie wystąpienia makr MFC TRY, CATCH, AND_CATCH, END_CATCH, THROW i THROW_LAST.

  2. 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)

  3. 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)
    
  4. 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++.

Zobacz też

Obsługa wyjątków