Condividi tramite


Differenze di gestione delle eccezioni

La differenza principale tra gestione delle eccezioni strutturata e gestione delle eccezioni C++ è che il modello di gestione delle eccezioni C++ commercia nei tipi, mentre nelle aziende del modello di gestione delle eccezioni strutturata c# con le eccezioni di un tipo (in particolare, unsigned int.Ovvero le eccezioni c# sono identificate da un valore intero senza segno, mentre le eccezioni C++ sono identificate da tipo di dati.Quando viene generata un'eccezione in C#, ogni gestore possibile eseguire un filtro che esamina il contesto di eccezione c# e determina se accettare l'eccezione, lo passa a un altro gestore, o lo ignorerà.Quando un'eccezione viene generata in C++, può essere di qualsiasi tipo.

Una seconda differenza è che il modello di gestione delle eccezioni strutturata c# è nota come “asincrono„ in quanto le eccezioni che si verificano secondario al flusso di controllo normale.Il meccanismo di gestione delle eccezioni C++ è totalmente “sincrono„, che indica che le eccezioni che si verificano solo quando vengono generate.

Se l'eccezione c viene generata in un programma C++, può essere gestita da un gestore di eccezioni strutturata tramite il filtro associata o da C++ catch gestore, qualsiasi elemento in modo dinamico più vicino al contesto di eccezione.Ad esempio, il seguente programma C++ genera l'eccezione c in C++ prova contesto:

Esempio

// exceptions_Exception_Handling_Differences.cpp
// compile with: /EHa
#include <iostream>

using namespace std;
void SEHFunc( void );

int main() {
   try {
      SEHFunc();
   }
   catch( ... ) {
      cout << "Caught a C exception."<< endl;
   }
}

void SEHFunc() {
   __try {
      int x, y = 0;
      x = 5 / y;
   }
   __finally {
      cout << "In finally." << endl;
   }
}
  
  

Ad esempio, il codice riportato di seguito installa una funzione personalizzata per la conversione e quindi genera l'eccezione c che viene eseguito il wrapping da SE_Exception classe:

// exceptions_Exception_Handling_Differences3.cpp
// compile with: /EHa
#include <stdio.h>
#include <eh.h>
#include <windows.h>

class SE_Exception {
private:
   SE_Exception() {}
   unsigned int nSE;

public:
   SE_Exception( SE_Exception& e) : nSE(e.nSE) {}
   SE_Exception(unsigned int n) : nSE(n) {}
   ~SE_Exception() {}
   unsigned int getSeNumber() { return nSE; }
};

void SEFunc() {
   __try {
      int x, y = 0;
      x = 5 / y;
    }
    __finally {
      printf_s( "In finally\n" );
   }
}

void trans_func( unsigned int u, _EXCEPTION_POINTERS* pExp ) {
   printf_s( "In trans_func.\n" );
   throw SE_Exception( u );
}

int main() {
   _set_se_translator( trans_func );
    try {
      SEFunc();
    }
    catch( SE_Exception e ) {
      printf_s( "Caught a __try exception with SE_Exception.\n" );
      printf_s( "nSE = 0x%x\n", e.getSeNumber() );
    }
}
  
  
  

Classe wrapper di eccezione c#

In un esempio semplice come il di sopra, l'eccezione c# può essere individuato solo dai puntini di sospensione () catch gestore.Nessuna informazione sul tipo o la natura dell'eccezione vengono passate al gestore.Durante questo metodo viene utilizzato, potrebbe essere necessario in alcuni casi di definire una trasformazione tra i due modelli di gestione delle eccezioni in modo che ogni eccezione di C# sia associata a una classe specifica.A questo scopo, è possibile definire la classe “wrapper„ di eccezione c, che può essere utilizzato o derivato da associare al tipo specifico della classe a eccezione di tipo c.In tal modo, ogni eccezione di C# può essere gestita da C++ catch gestore più separatamente dell'esempio precedente.

La classe wrapper disponga di un'interfaccia composta da alcune funzioni membro che determinano il valore dell'eccezione e l'accesso alle informazioni sul contesto estese di eccezione fornite dal modello di eccezione c#.È possibile inoltre definire un costruttore predefinito e un costruttore che accetta unsigned int argomento (per fornire la rappresentazione sottostante di eccezione c#) e un costruttore di copia bit per bit.L'esempio seguente è un'implementazione possibile della classe wrapper di eccezione c:

// exceptions_Exception_Handling_Differences2.cpp
// compile with: /c
class SE_Exception {
private:
   SE_Exception() {}
   SE_Exception( SE_Exception& ) {}
   unsigned int nSE;
public:
   SE_Exception( unsigned int n ) : nSE( n ) {}
   ~SE_Exception() {}
   unsigned int getSeNumber() {
      return nSE;
   }
};

Per utilizzare questa classe, si installa una funzione personalizzata per la conversione di eccezione c# definita dall'eccezione interna c il meccanismo di gestione delle eccezioni quando viene generata un'eccezione.Nella funzione di conversione, è possibile generare qualsiasi eccezione tipizzata (ad esempio SE_Exception tipo, o un tipo di classe derivato da SE_Exception) che può essere intercettata da una corrispondenza adatta C++ catch gestore.La funzione di conversione può restituire semplicemente, che indica che non gestita l'eccezione.Se la funzione stessa di conversione genera un'eccezione di tipo c, terminare viene chiamato.

Per specificare una funzione personalizzata per la conversione, chiamare _set_se_translator funzione con il nome della funzione di conversione lo come unico argomento.La funzione di conversione che si scrivono viene chiamata una volta per ogni chiamata di funzione nello stack che ha prova blocchi.Non esiste una funzione predefinita della conversione, se non si specifica una chiamando _set_se_translator, l'eccezione c# può essere rilevata solo dai puntini di sospensione catch gestore.

Vedere anche

Riferimenti

Combinazione di C () strutturata e eccezioni C++