Condividi tramite


Eccezioni: Modifiche alle macro di eccezione nella versione 3,0

Si tratta di un argomento avanzato.

Nelle versioni di MFC 3,0 e versioni successive, le macro di gestione delle eccezioni sono state modificate per utilizzare le eccezioni C++.In questo articolo descritto come tali modifiche possono influire sul comportamento del codice esistente che utilizza le macro.

Questo articolo vengono trattati i seguenti argomenti:

  • Tipi di eccezione e la macro di FERMO

  • Ri-generare le eccezioni

Tipi di eccezione e la macro di FERMO

Nelle versioni precedenti di MFC, la macro di CATCH utilizza le informazioni sul tipo di runtime MFC per determinare il tipo di eccezioni; il tipo di eccezioni è determinato, ovvero al sito catch.Con le eccezioni C++, tuttavia, il tipo di eccezioni è sempre determinato il sito di generazione dal tipo di eccezione generato.In questo modo le incompatibilità nei rari casi in cui il tipo del puntatore all'oggetto generato è diverso da quello dell'oggetto generato.

Nell'esempio seguente viene illustrato il risultato di questa differenza tra la versione di MFC 3,0 e versioni precedenti:

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

Questo codice si comporta in modo diverso nella versione 3,0 perché il controllo passa sempre al primo blocco catch con una dichiarazione dell'eccezione corrispondente.Il risultato dell'espressione throw

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

viene generato come CException*, anche se viene costruito quale CCustomException.La macro di CATCH in MFC versione 2,5 e utilizzi più a breve termine CObject::IsKindOf verificare il tipo in fase di esecuzione.Poiché l'espressione

e->IsKindOf(RUNTIME_CLASS(CException));

è true, i primi intercetti di blocco catch l'eccezione.Nella versione 3,0, che utilizza le eccezioni C++ per implementare molte delle macro di gestione delle eccezioni, il secondo blocco catch corrisponde CExceptiongenerato.

Il codice di questo tipo è raro.In genere viene visualizzato quando un oggetto eccezione viene passato a un'altra funzione che accetta **CException***generico, esegue l'elaborazione di “pre-tiro„ e infine genera l'eccezione.

Per ovviare a questo problema, spostare l'espressione throw dalla funzione nel codice chiamante e generare un'eccezione di tipo effettivo noto al compilatore quando viene generata l'eccezione.

Ri-Generare le eccezioni

Un blocco catch non è possibile generare lo stesso puntatore di eccezione che ha intercettato.

Ad esempio, questo codice è valido nelle versioni precedenti, ma sarà risultati imprevisti con la versione 3,0:

   TRY
   {
      // Do something to throw an exception.
      AfxThrowUserException();
   }
   CATCH( CException, e )
   {
      THROW( e );    // Wrong. Use THROW_LAST() instead
   }
   END_CATCH
}

Utilizzando THROW nel blocco catch fa sì che il puntatore e l'eliminazione, in modo che il sito esterno catch riceverà un puntatore non valido.Utilizzo THROW_LAST a eccezione e.

Per ulteriori informazioni, vedere eccezioni: Rilevazione e l'eliminazione delle eccezioni.

Vedere anche

Concetti

Gestione delle eccezioni in MFC