异常处理差异

结构化异常处理和 C++ 异常处理之间的主要差异在于 C++ 异常处理模型在类型,处理,而 C 结构化异常处理模型可以具有类型的异常 (具体而言, unsigned int。 即 C 异常由无符号整数值标识,,而 C++ 异常由数据类型确定的。 在引发异常时在 C 中时,每个可能的处理程序执行是否检查 C 异常上下文并确定接受异常,将对某些其他处理程序或忽略它的筛选器。 当异常在 C++ 中引发,它可以是任何类型。

第二个差异是 C 结构化异常处理模型称为 “异步”异常发生辅助为正常控制流。 C++ 异常处理机制完全是 “同步,”表示发生异常,仅当它们会引发。

如果 c. 异常在 c. C++ 程序中引发,它可以处理由其关联的筛选器的结构化异常处理程序或由 c. C++ catch 处理程序,后者自异常上下文是动态的。 例如,下面的 C++ 程序引发可在 c. C++ 尝试 上下文内的 c. 异常:

示例

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

例如,下面的代码安装自定义转换功能,然后引发由 SE_Exception 类包装的 c. 异常:

// 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 异常包装类

在一个简单示例中 (如在顶层, C 异常可以通过省略号 () catch 处理程序仅捕获。 有关异常的类型或谓词的信息不传递到处理程序。 在此方案中工作时,您在某些情况下可能需要定义两种异常处理模型之间的转换,以便每个 C 异常与特定类。 为此,您可以定义 c. 异常 “包装”类,可以从为了属性使用或派生特定类类型到 C++. 异常。 通过这种方式,每个 C 异常可由 c. C++ catch 处理程序单独进程比前一个示例。

包装类可能具有包括确定异常的值,因此,访问扩展的异常上下文信息由 C 异常模型提供的一些成员函数的接口。 您可能还希望按位定义默认构造函数并接受 unsigned int 参数的构造函数 (提供基础 C 异常表示) 和一个复制构造函数。 下面是 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;
   }
};

若要使用此类,则安装由内部异常处理机制 c. 异常调用每次引发的自定义 C 异常转换函数。 在转换函数中,可以引发可被适当的匹配 C++ catch 处理程序捕获的所有类型化异常 (可能 SE_Exception 类型或从 SE_Exception派生的类类型)。 转换函数可以返回,指示不处理异常。 如果转换功能来增强 c. 异常, 停止 调用。

若要指定自定义转换功能,请调用相关的函数的名称 _set_se_translator 函数作为其唯一参数。 转换函数编写为具有 尝试 的堆栈中的每个函数调用一次调用块。 没有默认的转换函数;如果没有通过调用 _set_se_translator指定一, C 异常可能由省略号 catch 处理程序仅捕获。

请参见

参考

混合C (结构)和C++异常