Freigeben über


Ausnahmebehandlungs-Unterschiede

Der Hauptunterschied zwischen strukturierten Ausnahmebehandlung und die C++-Ausnahmebehandlung ist, dass die C++-Ausnahmebehandlung die Modell behandelt, in Typen behandelt, während die Modell abkommen C-strukturierter Ausnahmebehandlung mit Ausnahmen von einem Typ, der unsigned int.Das bedeutet, dass C-Ausnahmen durch einen Ganzzahlwert ohne Vorzeichen bezeichnet, während von C++-Ausnahmen Datentyp angegeben werden.Wenn eine Ausnahme in C ausgelöst wird, führt jeder beliebige Handler einen Filter aus, der den C-Ausnahme Elementkontext validiert, und ob die Ausnahme angegeben wird, akzeptiert, sie zu einem anderen Handler führt oder sie ignoriert.Wenn eine Ausnahme in C++ ausgelöst wird, kann sie von jedem Typ.

Ein zweiter Unterschied besteht darin, dass das Modell C-strukturierter Ausnahmebehandlung dadurch so genannte „asynchron“ dass Ausnahmen sekundär in den normalen Programmablauf auftreten.Die C++-Ausnahmebehandlung die Mechanismus ist vollständig verarbeitet, synchron „,“ bedeutet, dass sich der Ausnahmen nur auftreten, wenn sie ausgelöst werden.

Wenn Wechselstrom-Ausnahme in einem C++-Programm ausgelöst wurde, kann sie von einem strukturierte Ausnahmehandler mit dem zugeordneten Filter oder catch-Handler Ein C++-Compiler behandelt werden, die auf den Ausnahmekontext dynamisch näher befindet.Zum Beispiel löst das folgenden C++-Programm Wechselstrom-Ausnahme im Kontext try ++ im C-Format aus:

Beispiel

// 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;
   }
}
  
  

installiert beispielsweise der folgende Code eine benutzerdefinierte Funktion Übersetzungs und anschließend wird Wechselstrom-Ausnahme aus, die von der SE_Exception-Klasse umschlossen wird:

// 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() );
    }
}
  
  
  

C-Ausnahme-Wrapperklasse

In einem einfachen Beispiel wie Sie das oben stehende, die C-Ausnahme kann nur von einem catch-Handler mit den Auslassungspunkten (...) abgefangen werden.Es werden keine Informationen über den Typ oder die Art der Ausnahme an den Handler übermittelt werden.Während diese Methode funktioniert, in einigen Fällen müssen Sie möglicherweise eine Transformation zwischen den beiden Ausnahmebehandlung modellen definieren, damit jede C-Ausnahme mit einer bestimmten Klasse zugeordnet ist.Hierzu können Sie Wechselstrom-Ausnahme „Wrapper“ für die Klasse definieren, die vom Attribut ein spezieller Klassentyp verwendet Wechselstrom-Ausnahme oder abgeleitet werden kann.Wenn Sie dies der Fall ist, kann jede C-Ausnahme Ein catch-Handler aus dem vorhergehenden Beispiel als C++-Compiler separat behandelt werden.

Die Wrapperklasse könnte eine Schnittstelle, die aus mehreren Memberfunktionen besteht, die den Wert der Ausnahme bestimmen und die erweiterten Ausnahmekontext C-Ausnahme Informationen zugreifen, die vom Modell bereitgestellt werden.Sie können auch einen Standardkonstruktor und einen Konstruktor, der ein unsigned int-Argument (für die zugrunde liegende Darstellung C-Ausnahme bereitstellen) akzeptiert, und um einen bitweisen Kopierkonstruktor definieren.Im Folgenden wird eine mögliche Implementierung der Wrapperklasse für Wechselstrom-Ausnahme:

// 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;
   }
};

Um diese Klasse zu verwenden, installieren Sie eine benutzerdefinierte C-Ausnahme übersetzungs die Funktion von der internen Wechselstrom-Ausnahme des Mechanismus für die Ausnahmenbehandlung jedes Mal ausgelöst wird.Innerhalb der Funktion Übersetzungs können Sie jede typisierte Ausnahme (möglicherweise einen SE_Exception-Typ oder von abgeleiteten SE_Exceptioneinen Klassentyp auslösen), die von einem entsprechenden übereinstimmenden C++-catch-Handler abgefangen werden kann.Die Funktion kann einfach Übersetzungs zurückkehren, die angibt, dass sie nicht die Ausnahme behandelt hat.Wenn die Funktion selbst Übersetzungs Wechselstrom-Ausnahme auslöst, wird Sie beenden aufgerufen.

Um eine benutzerdefinierte Funktion Übersetzungs anzugeben, rufen Sie die _set_se_translator-Funktion mit dem Namen der Funktion Übersetzungs als einzelnes Argument an.Die Funktion Übersetzungs, die Sie schreiben, wird einmal für jeden Aufruf der Funktion im Stapel aufgerufen, der try-Blöcke verfügt.Es gibt keine Funktion, Übersetzungs Standard Wenn Sie ein nicht angeben, indem Sie _set_se_translatoraufrufen, kann die C-Ausnahme aus einem Auslassungszeichen catch-handler nur abgefangen werden.

Siehe auch

Referenz

Die Kombination von C- (strukturiert) und C++-Ausnahmen