跳到主要内容

异常处理深度解析

  • 问题

    如果在main函数中抛出异常会发生什么?

  • 如果异常不处理,最后会传到哪里?

  • 下面的代码输出什么?

    class Test {
    public:
    Test() {
    cout<<"Test()"<<endl;
    }

    ~Test() {
    cout()<<"~Test()";
    }
    }

    int main() {
    static Test t;
    throw 1;
    return 0;
    }

编程实验

  • 异常的最终处理?

    #include <iostream>

    using namespace std;

    class Test {
    public:
    Test() {
    cout << "Test()";
    cout << endl;
    }

    ~Test() {
    cout << "~Test()";
    cout << endl;
    }
    };


    int main(){
    static Test t;
    throw 1;
    return 0;
    }

异常处理深度分析

  • 如果异常无法被处理,terminate()结束函数会被自动调用
  • 默认情况下,terminate()调用库函数abort()终止程序
  • abort()函数使得程序执行异常而立即退出
  • C++支持替换默认的terminate()函数实现
  • terminate()函数的替换
    • 自定义一个无返回值无参数的函数
      • 不能抛出任何异常
      • 必须以某种方式结束当前程序
    • 调用set_terminate()设置自定义的结束函数
      • 参数类型为void(*)()
      • 返回值为默认的terminate()函数入口地址

编程实验

  • 自定义结束函数

    #include <iostream>
    #include <cstdlib>
    #include <exception>

    using namespace std;

    void my_terminate() {
    cout << "void my_terminate()" << endl;
    exit(1);
    }

    class Test {
    public:
    Test() {
    cout << "Test()";
    cout << endl;
    }

    ~Test() {
    cout << "~Test()";
    cout << endl;
    }
    };


    int main(){
    set_terminate(my_terminate);
    static Test t;

    throw 1;

    return 0;
    }
  • 问题

    如果析构函数中抛出异常会发生什么情况?

  • 析构函数抛出异常

    #include <iostream>
    #include <cstdlib>
    #include <exception>

    using namespace std;

    void my_terminate() {
    cout << "void my_terminate()" << endl;
    // exit(1);
    abort();
    }

    class Test {
    public:
    Test() {
    cout << "Test()";
    cout << endl;
    }

    ~Test() {
    cout << "~Test()";
    cout << endl;

    throw 2;
    }
    };


    int main() {
    set_terminate(my_terminate);
    static Test t;
    throw 1;
    return 0;
    }

小结

  • 如果异常没有被处理,最后terminate()结束整个程序
  • terminate()是整个程序释放系统资源的最后机会
  • 结束函数可以自定义,但不能继续抛出异常
  • 析构函数中不能抛出异常,可能导致terminate()多次调用