C++异常处理 set_terminate

1.C++异常处理
在MFC中应使用C++的异常处理机制,不推荐使用MFC的宏
为了使C++异常处理可用,需要进行如下设置:工程->设置->C/C++ 选项卡->分类 C++语言->允许异常处理。或者使用/GX编译选项,默认情况下是/GX-
C++的异常处理结构为:
try{
//可能引发异常的代码
}catch(type_1 e)
{
// type_1类型异常处理
}catch(type_2 e)
{
// type_2类型异常处理
}catch (...)//会捕获所有未被捕获的异常,必须最后出现
{

}
在C++中,throw抛出异常的特点有:
  (1)可以抛出基本数据类型异常,如int和char等;
  (2)可以抛出复杂数据类型异常,如结构体(在C++中结构体也是类)和类;
  (3)C++的异常处理必须由调用者主动检查。一旦抛出异常,而程序不捕获的话,那么abort()函数就会被调用,弹出如图1所示的对话框,程序被终止;
    (4)可以在函数头后加throw([type-ID-list])给出异常规格,声明其能抛出什么类型的异常。type-ID-list是一个可选项,其中包括了一个或多个类型的名字,它们之间以逗号分隔。如果函数没有异常规格指定,则可以抛出任意类型的异常。
C++的标准异常
namespace std
{
 //exception派生
 class logic_error; //逻辑错误,在程序运行前可以检测出来

 //logic_error派生
 class domain_error; //违反了前置条件
 class invalid_argument; //指出函数的一个无效参数
 class length_error; //指出有一个超过类型size_t的最大可表现值长度的对象的企图
 class out_of_range; //参数越界
 class bad_cast; //在运行时类型识别中有一个无效的dynamic_cast表达式
 class bad_typeid; //报告在表达试typeid(*p)中有一个空指针p

 //exception派生
 class runtime_error; //运行时错误,仅在程序运行中检测到

 //runtime_error派生
 class range_error; //违反后置条件
 class overflow_error; //报告一个算术溢出
 class bad_alloc; //存储分配错误
}

exception类的原型:
请注意观察上述类的层次结构,可以看出,标准异常都派生自一个公共的基类exception。基类包含必要的多态性函数提供异常描述,可以被重载。
class exception
{
 public:
  exception() throw();
  exception(const exception& rhs) throw();
  exception& operator=(const exception& rhs) throw();
  virtual ~exception() throw();
  virtual const char *what() const throw();
};

函数what():返回一个表示异常的字符串。
从exception类派生一个自己的类:
#include <iostream>
#include <exception>
using namespace std;
class myexception:public exception
{
 public:
 myexception():exception("一个重载exception的例子")
 {}
};
int main()
{
 try
 {
  throw myexception();
 }
 catch (exception &r) //捕获异常
 {
  cout << "捕获到异常:" << r.what() << endl;
 }
 return 0;
}
  程序运行,输出:
  捕获到异常:一个重载exception的例子
一般的,我们直接以基类捕获异常,例如,本例中使用了
catch (exception &r)
  然后根据基类的多态性进行处理,这是因为基类中的what函数是虚函数。
2.捕获所有异常
#include <eh.h>
#include <process.h>
#include <iostream.h>
typedef struct tagPoint //定义Point结构体(类)
{
         int x;
         int y;
} Point;

static void f()    //扔出Point异常的函数
{
         Point p;
         p.x = 0;
         p.y = 0;
         throw p;
}

int main()
{
         try
         {      
            // throw 100; //抛出 int 型异常
            // throw "a string"; //抛出字符串型异常
              f(); //抛出Point异常
         }
         catch (int) //捕获int异常
         {
                   cout<<"捕获到int异常"<<endl;
         }
         catch (char *str) //捕获Point异常
         {
                   cout<<"捕获到字符型串异常"<<endl;
         }
         catch (Point e) //捕获Point异常
         {
                   cout<<"捕获到Point自定义类型的异常"<<endl;
         }
         catch (...) //其它所有类型
         {
                   cout<<"捕获到其它类型的异常"<<endl;
         }
         return 0;
}
3.set_terminate:
处理未设置异常处理函数的异常,个人认为可以用catch (...){}而不用它
需要头文件<eh.h>
多线程程序中,各个terminate函数是独立的,每个线程都有其terminate函数
在调试器不存在的情况下才工作
Terminate函数中不能再抛出异常
如果我们不设置terminate函数,则默认情况下调用abort函数

#include <eh.h>
#include <process.h>
#include <iostream.h>
void term_func();
void main()
{
    int i = 10, j = 0, result;
    set_terminate( term_func );
    try
    {
        if( j == 0 )
            throw "Divide by zero!";   //抛出异常,由terminate函数捕获,
        else
            result = i/j;
    }
    catch( int ) //不会由该函数捕获
    {
        cout << "捕获到整型异常.\n";
    }
    cout << "This should never print.\n";
}
void term_func()
{
    cout << "term_func() was called by terminate().\n";
    // ... cleanup tasks performed here
    // If this function does not exit, abort is called.
    exit(-1);
}

原文链接: https://www.cnblogs.com/qintangtao/archive/2012/12/07/2807703.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++异常处理 set_terminate

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/71755

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午3:02
下一篇 2023年2月9日 下午3:02

相关推荐