Wyjątki: używanie makr MFC i wyjątków języka C++

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 wyjęciu z zakresu, podczas gdy kod używający słów kluczowych obsługi wyjątków nie jest. 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 używający słów kluczowych nie; 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 stert po dwukrotnym usunięciu wyjątku.

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 kończy się z "wewnętrznego" bloku CATCH . Użycie makra THROW_LAST zamiast instrukcji THROW spowoduje, że "zewnętrzny" blok 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 znajdującego trysię 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.

Zobacz też

Obsługa wyjątków