Compartilhar via


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.

Consulte também

Referência

Mistura de C (estruturado) e exceções do C++