70、外传1

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

#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>//c++标准库中的,与异常有关
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);    //调用my_terminate
    static Test t;    
    throw 1;
    return 0;

}

面试题:如果析构函数中抛出异常会发生什么?

第一个析构函数是用于释放资源的地方,如果抛出异常,有可能导致资源得不到正确的释放。第二点是有可能导致全局的结束函数terminate被重复的调用,这是极其可怕的,有可能使系统进入不稳定状态。

#include <iostream>
#include <cstdlib>
#include <exception>
using namespace std;
void my_terminate()
{
    cout << "void my_terminate()" << endl;
    // exit(1);  //调用 set_terminate(my_terminate);,
    abort();  //默认为这个如果是上边的,可能析构函数抛出异常,重复删除。调用abort之前可能打印字符串或者弹出个窗口
}

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

    ~Test() 
    {
        cout << "~Test()"; 
        cout << endl;        
        throw 2; //调用  set_terminate(my_terminate);
    }
};
int main()
{
    set_terminate(my_terminate);
    
    static Test t;
    
    throw 1;   //开始调用    set_terminate(my_terminate);

    return 0;

}

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

猜你喜欢

转载自blog.csdn.net/ws857707645/article/details/80300795
70