外传篇 1 - 异常处理深度解析

0、先修知识

C++异常处理(上)

C++异常处理(下)

1、问题

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

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

下面的代码输出什么? 

2、编程实验 

异常的最终处理    E1-1.cpp 

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

BCC101

VS2015

VS2010会弹出一个窗口

g++

3、异常处理深度解析 

如果异常无法被处理terminate()结束函数会被自动调用 

默认情况下,terminate()调用库函数abort()终止程序 

abort()函数使得程序执行异常而立即退出 

C++支持替换默认的terminate()函数实现 

terminate()函数的替换 

   -自定义一个无返回值无参数的函数 

                   不能抛出任何异常 

                   必须以某种方式结束当前程序 

   - 调用set_ terminate()设置自定义的结束函数 

                    参数类型为void (*) () 

                                返回值为默认的terminate()函数入口地址 

4、编程实验 

自定义结束函数    El-2.cpp 

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

 

5、C++中的return,exit,abort

exit():
           在调用时,会做大部分清理工作,但是决不会销毁局部对象,因为没有stack unwinding。

会进行的清理工作包括:销毁所有static和global对象,清空所有缓冲区,关闭所有I/O 通道。

终止前会调用经由atexit()登录的函数,atexit如果抛出异常,则调用terminate():
abort():
            调用时,不进行任何清理工作。直接终止程序。
retrun:
            调用时,进行stack unwinding,调用局部对象析构函数,清理局部对象。

            如果在main中,则之后再交由系统调用exit()。

6、面试题 

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

7、编程实验 

析构函数抛出异常    E1-3.cpp 

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

               不安全,所以推荐使用abort(),这也是标准库中使用abort()的原因

8、小结 

如果异常没有被处理,最后terminate()结束整个程序 

terminate()是整个程序释放系统资源的最后机会 

结束函数可以自定义,但不能继续抛出异常 

析构函数中不能抛出异常,可能导致terminate()多次调用 

猜你喜欢

转载自blog.csdn.net/qq_39654127/article/details/81329085
今日推荐