Różnice obsługi wyjątków
Główna różnica pomiędzy structured exception handling i obsługę wyjątków C++ jest, że obsługi modelu okazje typów wyjątków C++, podczas gdy c structured exception model obsługi zajmuje wyjątki jednego typu — w szczególności, unsigned int.Oznacza to, że c wyjątki są identyfikowane przez wartość całkowitą bez znaku, wyjątki C++ są określone przez typ danych.Gdy tworzony jest wyjątek w C, każdy możliwe program obsługi wykonuje filtru, który bada kontekst c wyjątek i określa, czy akceptować wyjątek, przekazać niektóre procedury obsługi lub zignorować.Gdy wyjątek jest generowany w języku C++, mogą być dowolnego typu.
Druga różnica jest, że wzór c structured exception handling jest mowa "asynchroniczny" w tym wyjątki występują drugorzędny w stosunku do normalnej przepływ sterowania.Wyjątek C++ mechanizmu obsługi jest całkowicie "synchroniczne,", co oznacza wyjątki występują, tylko gdy one są generowane.
Jeśli wyjątek c jest wywoływane w programie C++, mogą być obsługiwane przez obsługi structured exception z jego skojarzonego filtru lub C++ połowu obsługi, nastąpi dynamicznie położoną bliżej do kontekstu wyjątku.Na przykład, następujący program w języku C++ wzbudza wyjątek c wewnątrz C++ Spróbuj kontekstu:
Przykład
// 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;
}
}
Na przykład, poniższy kod instaluje funkcji niestandardowych tłumaczenia i następnie podnosi c wyjątek, który jest pakowane przez SE_Exception klasy:
// 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 klasy otoki wyjątek
W prosty przykład, podobnie jak wyżej, C wyjątku można złowionych tylko przez wielokropek (...) połowu obsługi.Informacje o typu lub rodzaju wyjątek nie jest przekazywana do programu obsługi.Podczas, gdy metoda ta działa, w niektórych przypadkach może należy zdefiniować transformacji między modelami dwóch wyjątków, dzięki czemu każdy wyjątek c jest skojarzony z określonej klasy.Aby to zrobić, można zdefiniować klasy "otoki" C wyjątek, który może być używany lub pochodną do atrybutu typu określonej klasy c wyjątku.Dzięki temu każdy wyjątek c mogą być obsługiwane przez C++ połowu obsługi bardziej oddzielnie niż w poprzednim przykładzie.
Klasy otoki może mieć interfejsu, składającego się z niektórych funkcji elementów członkowskich określające wartość wyjątku i że dostęp do informacji kontekstu rozszerzone wyjątek, świadczone przez model c wyjątek.Można również zdefiniować konstruktora domyślnego i Konstruktor, który akceptuje unsigned int argument (zapewnienie podstawowej reprezentacji wyjątek C) i operatory kopiujący.Poniżej przedstawiono możliwe implementacji klasy otoki c wyjątek:
// 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;
}
};
Aby używać tej klasy, należy zainstalować funkcji tłumaczenia niestandardowe wyjątek C, która jest wywoływana przez wewnętrzny wyjątek każdorazowo c wyjątek mechanizmu obsługi.Wewnątrz funkcji tłumaczenia, można throw każdy wyjątek maszynowy (prawdopodobnie SE_Exception , lub typu klasy pochodne SE_Exception), może być złowionych przez właściwe C++ dla pasujących połowu obsługi.Funkcja tłumaczenie może po prostu zwracać, wskazuje, że nie obsłużył wyjątku.Jeżeli sama funkcja tłumaczenie wzbudza wyjątek C, Zakończenie jest wywoływana.
Aby określić funkcję tłumaczenia niestandardowe, należy wywołać _set_se_translator funkcji o nazwie funkcji tłumaczenia jako pojedynczy argument.Można napisać funkcję tłumaczenia jest wywoływana raz dla każdego wywołania funkcji na stosie, który ma Spróbuj bloków.Nie ma żadnej funkcji tłumaczenia domyślne; Jeżeli nie określisz żadnej przez wywołanie _set_se_translator, wyjątek c może być tylko złowionych przez wielokropek połowu obsługi.