zoukankan      html  css  js  c++  java
  • 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);
    }

  • 相关阅读:
    Java实现 LeetCode 211 添加与搜索单词
    跨平台Unicode与UTF8互转代码
    C++转换unicode utf-8 gb2312编码
    c++ ANSI、UNICODE、UTF8互转
    Visual C++ unicode and utf8 转换
    Unicode和UTF-8的关系
    boost uuid 学习笔记
    boost uuid
    Darwin Streaming server 的 Task 类
    VS2010下编译安装DarwinStreamingServer5.5.5
  • 原文地址:https://www.cnblogs.com/qintangtao/p/2807703.html
Copyright © 2011-2022 走看看