Cpp深入:异常体系结构


1. 异常简介

  1. 函数异常列表

  2. 堆栈解退

  3. 标准库exception类型简介

  4. 继承中的异常

  5. 异常何时迷失?

  6. 异常处理最佳实践

  7. 异常简介

c++中的异常使用关键字try{} catch(Type ){}来捕获。可以使用throw关键字抛出异常。如果在程序执行过程中出现了未捕获的异常的话 ,默认的情况是终止程序的运行。

view plaincopy to clipboardprint?
1. intmain()
2. {
3. try
4. {
5. // 这里可以抛出class或者是简单类型:字符串,int等
6. throw"exception";
7. }
8. catch(constchar* err)
9. {
10. // 选择异常处理或者是
11. cout << err << endl;
12.
13. // 如果异常是无法处理的话,选择重新抛出异常
14. // throw;
15. }
16. return0;
17. }

  1. 函数异常列表

函数异常列表指明了该函数可能抛出的异常的类型,如果函数引发了除了函数异常列表之外的异常,那么默认的情况是调用终止程序运行。如果程序想要执行终止程序运行的话 ,可以使用abort函数和exit函数,exit函数刷新io缓冲区,abort函数不刷新。同时exit和abort函数将不会调用堆栈中的变量的析构函数。

view plaincopy to clipboardprint?
1. voidthrowExxceptionFunc()throw(constchar*,double, bad_cast)
2. {
3. }

  1. 堆栈解退

如下图所示,如果在深层嵌套的函数中发生异常,那么程序将不断释放堆栈中的内存,直到能够找到一个合适的catch块来捕获该异常,这个过程中堆栈对象的类的析构函数将被调用。

Cpp深入:异常体系结构

  1. 标准库exception类型简介

cpp标准库中提供了一系列的异常类。在头文件中包含:exception,bad_exception,bad_alloc异常类型的定义,文件中定义了logic_error,domain_error,invalid_argumentlength_error,out_of_range,runtime_error,overflow_error等异常,我们可以选择一个合适的类型来继承,从而实现自定义异常类型。

Cpp深入:异常体系结构

view plaincopy to clipboardprint?
1. classMyRuntimeException :publicruntime_error
2. {
3. // 构造函数
4. MyRuntimeException(conststring& msg) : runtime_error(msg)
5. {
6. }
7. // 析构函数
8. ~MyRuntimeException()
9. {
10. }
11. constchar* what()const
12. {
13. returnruntime_error::what();
14. }
15. };

  1. 继承中的异常

如果子类重写了父类的某个方法的话,那么需要保证子类的该方法的函数异常列表需要和父类的相同或者是继承的关系(vc没有实现该特性,可能出现忽略 C++ 异常规范,但指示函数不是 __declspec(nothrow)警告)。

view plaincopy to clipboardprint?
1. classBase
2. {
3. public:
4. virtualvoidfunc()throw(exception) { }
5. };
6. classSub :publicBase
7. {
8. voidfunc()throw(runtime_error)
9. {
10. }
11. };

  1. 异常何时迷失?

意外unexpected异常:如何函数抛出了未在函数异常列表中的异常类型的话,将引发意外异常。默认将调用unexpected函数。

未捕获异常:异常已经引发,但是没有catch块来处理该异常。默认是调用terminate函数。

上面两种情况默认都是终止程序运行,但是可以设置出现上面两种情况后调用的处理函数handler function。

view plaincopy to clipboardprint?
1. // 异常处理
2. #include
3. #include
4. usingnamespacestd;
5. voidmy_terminate()
6. {
7. cout <<"in my_terminate"<< endl;
8. }
9. intmain()
10. {
11. set_terminate(my_terminate);
12.
13. throwexception("exception");
14. return0;
15. }

下面的代码将在vc(vs2008)中无法运行,vc没有实现函数异常列表特性。

view plaincopy to clipboardprint?
1. // 异常处理
2. #include
3. #include
4. usingnamespacestd;
5. voidmy_unexpected_handler()
6. {
7. cout <<"in my_terminate"<< endl;
8. }
9. voidfun()throw(int)
10. {
11. throwexception("exception");
12. }
13. intmain()
14. {
15. set_unexpected(my_unexpected_handler);
16.
17. fun();
18. return0;
19. }

  1. 异常处理最佳实践

  2. 在捕获异常时使用引用而不是值类型

  3. 异常中如何处理内存申请和释放?

view plaincopy to clipboardprint?
1. voidfunc()
2. {
3. constintARRAY_SIZE = 10;
4. double ptr=newdouble[ARRAY_SIZE];
5. try
6. {
7. throw"exception";
8. }
9. catch(constchar
e)
10. {
11. delete[] ptr;
12. }
13. // 做一些事情
14. delete[] ptr;
15. }


原文链接: https://www.cnblogs.com/xuqiang/archive/2011/04/25/2027679.html

欢迎关注

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

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

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

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

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

(0)
上一篇 2023年2月8日 上午2:24
下一篇 2023年2月8日 上午2:24

相关推荐