Diferenças de tratamento de exceção
A principal diferença entre a manipulação de exceção estruturada e manipulação de exceção do C++ é que o modelo de negócios em tipos de manipulação de exceção de C++, enquanto o c modelo de manipulação de exceção estruturada lida com exceções de um tipo — especificamente, unsigned int.Ou seja, o c exceções são identificadas por um valor inteiro não assinado, ao passo que as exceções do C++ são identificadas pelo tipo de dados.Quando uma exceção é gerada em C, cada manipulador de possível executa um filtro que examina o contexto de exceção c e determina se deve aceitar a exceção, passá-lo para algum outro manipulador ou ignorá-la.Quando uma exceção é lançada em C++, pode ser de qualquer tipo.
Uma segunda diferença é que o modelo de tratamento de exceção estruturada c é mencionado como "assíncrona" em que as exceções ocorrem secundário para o fluxo normal de controle.A mecanismo de tratamento de exceção do C++ é totalmente "sincronizada", o que significa que exceções ocorrem somente quando eles são lançados.
Se uma exceção de c é aumentada em um programa em C++, ele pode ser manipulado por um manipulador de exceção estruturada com seu filtro associado ou por um C++ catch o manipulador, que for dinamicamente mais perto para o contexto de exceção.Por exemplo, o seguinte programa C++ dispara uma exceção c dentro de um C++ tente contexto:
Exemplo
// 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;
}
}
Por exemplo, o código a seguir instala uma função de conversão personalizado e, em seguida, gera uma exceção de c que é envolvida pela 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 de Wrapper de exceção c
Um exemplo simples, como o anterior, a exceção c pode ser detectada apenas por reticências (...) catch manipulador.Nenhuma informação sobre o tipo ou natureza da exceção é comunicada ao manipulador.Embora esse método funcione, em alguns casos você talvez precise definir uma transformação entre os modelos de manipulação de exceção de dois, para que cada exceção c está associada uma classe específica.Para fazer isso, você pode definir uma classe de "empacotador" exceção C, que pode ser usada ou derivada de um tipo específico de classe de atributo a uma exceção de C.Fazendo isso, cada exceção c pode ser manipulada por um C++ catch manipulador separadamente que em exemplo anterior.
A classe de wrapper pode ter uma interface que consiste em algumas funções de membro que determinam o valor da exceção e que acessar as informações de contexto de exceção estendida fornecidas pelo modelo de exceção C.Talvez você queira definir um construtor padrão e um construtor que aceita um unsigned int argumento (para fornecer a representação de exceção c subjacente) e um construtor de cópia bit a bit.A seguir está uma possível implementação de uma classe de wrapper de exceção 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;
}
};
Para usar essa classe, você deve instalar uma função de conversão de c de exceções personalizado chamado pela mecanismo de cada vez que uma exceção c de manipulação de exceção interna.Dentro de sua função de conversão, você pode lançar qualquer exceção digitada (talvez um SE_Exception tipo ou um tipo de classe derivada de SE_Exception) que pode ser detectada por um C++ correspondente apropriada catch manipulador.A função de conversão pode simplesmente retornar, o que indica que ele não identificou a exceção.Se a própria função de conversão gera uma exceção de C, Encerrar é chamado.
Para especificar uma função de conversão personalizado, chame o _ set_se_translator função com o nome de sua função de conversão como seu único argumento.A função de conversão que você escreve é chamada uma vez para cada chamada de função na pilha que tem tente blocos.Não há nenhuma função de conversão do padrão; Se você não especificar uma chamando _set_se_translator, a exceção c só pode ser detectada por reticências catch manipulador.