Udostępnij za pośrednictwem


Wyjątki: zmiany w makrach wyjątków w wersji 3.0

To jest temat zaawansowany.

W MFC wersja 3.0 i nowsze zostały zmienione makra obsługi wyjątków obsłudze języka C++ wyjątki.W tym artykule informuje o tym, jak te zmiany mogą wpływać na zachowanie istniejącego kodu, który używa makr.

W tym artykule omówiono następujące tematy:

  • Typy wyjątków i makra CATCH

  • Ponownego generowania wyjątków

Typy wyjątków i makra CATCH

We wcześniejszych wersjach programu MFC połowu makra używane MFC typów w czasie wykonywania informacje w celu określenia typu wyjątku; Typ wyjątku jest określana, innymi słowy, w witrynie catch.Z wyjątkami C++ jednak typ wyjątku jest zawsze określane w witryny rzut przez typu obiektu wyjątek, który jest generowany.Spowoduje to niezgodności w rzadkich przypadkach, gdy typ wskaźnika do obiektu wyrzucony różni się od typu obiektu wyrzucony.

Poniższy przykład ilustruje konsekwencją tej różnicy między MFC w wersji 3.0 i starszych wersji:

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 pierwszego połowu blok z pasującą deklarację wyjątek.Wynik wyrażenia throw

THROW( (CException*) new CCustomException() );

jest generowany w CException *, mimo że jest skonstruowany jako CCustomException.Połowu makro w MFC wersje 2.5 i wcześniejszych zastosowań CObject::IsKindOf do testowania typu w czasie wykonywania.Ponieważ wyrażenie

e->IsKindOf(RUNTIME_CLASS(CException));

jest to PRAWDA, pierwszy blok catch przechwytuje wyjątek.W wersji 3.0, która używa języka C++ wyjątki do zaimplementowania wielu makr obsługi wyjątków, drugi blok catch odpowiada wyrzucony CException.

Kod podobny do tego jest mało prawdopodobna.Zwykle pojawia się kiedy obiekt wyjątku jest przekazywana do innej funkcji, która akceptuje rodzajowego CException *, przetwarza "throw wstępne" i wreszcie zgłasza wyjątek.

Aby obejść ten problem, Przenieś wyrażenie rzut od funkcji do kodu wywołującego i zgłosić wyjątek rzeczywisty typ znane w kompilatorze w chwili wygenerowania wyjątku.

Ponownego generowania wyjątków

Blok catch nie można zgłosić sam wskaźnik wyjątek, który złapał.

Na przykład, ten kod był ważny w poprzednich wersjach, ale będzie miał nieoczekiwane wyniki z 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ą RZUCIĆ w połowu blok powoduje, że wskaźnik e do usunięcia, tak aby witryny zewnętrznej połowu otrzyma nieprawidłowego wskaźnika.Use THROW_LAST to re-throw e.

Aby uzyskać więcej informacji, zobacz wyjątki: wyjątków połowu i usuwania.

Zobacz też

Koncepcje

Obsługa wyjątków w MFC