C++异常的理解
2016-10-23 14:37
218 查看
错误处理技术
1.终止程序(段错误)
2.返回错误码
3.返回合法值
4.调用一个预先设置的出现错误时调的函数(回调函数)
异常处理
-当一个函数发现自己无法处理的错误时抛出异常,让函数的调用者直接或间接的处理这个问题。
异常的抛出和捕获
- 异常是通过抛出对象而引发的,对象的类型决定了应该激活哪个处理代码。
- 处理代码是与该对象类型匹配且离抛出异常位置最近的哪个
- 抛出异常后会释放局部存储对象,所处被抛出的对象叶欢给操作系统了,throw会初始化一个抛出特殊的异常对象副本(匿名对象),异常对象由编译管理,对象传给对应的catch处理后撤销。
栈展开
- 抛出异常的时候,暂停当前函数的执行,开始查找对应的匹配catch。
- 首先在throw本身是否在团员块内部,如果是查找catch,如果有匹配的,就处理;如果没有匹配的,则退出当前函数栈,继续在调用函数的栈中查找;如果到main函数的栈依旧没有找到匹配的,就终止程序。
异常捕获的匹配规则
-异常对象类型与catch的类型必须完全匹配
例外:
1.从非const对象到const对象。
2.从派生类型到基类类型的转换。
3.数组转换为指向数组的指针,函数转换为指向函数的指针。
运行结果如下:
异常的重新抛出
有可能单个catch不能完全处理一个异常,在进行一些校正处理后,希望再交给更外层的调用链函数来处理,catch则可以通过重新将异常传递给上层的函数来进行处理。
运行结果如下:
异常 构造函数&析构函数
构造函数完成对象的构造和初始化,要保证不在构造函数中抛出异常,否则可能导致对象不完整或没有完全初始化
析构函数 主要完成资源的清理,保证不在析构函数中抛出异常,否则导致资源泄漏(内存泄漏,句柄未关闭等)。
1.终止程序(段错误)
2.返回错误码
3.返回合法值
4.调用一个预先设置的出现错误时调的函数(回调函数)
异常处理
-当一个函数发现自己无法处理的错误时抛出异常,让函数的调用者直接或间接的处理这个问题。
异常的抛出和捕获
- 异常是通过抛出对象而引发的,对象的类型决定了应该激活哪个处理代码。
- 处理代码是与该对象类型匹配且离抛出异常位置最近的哪个
- 抛出异常后会释放局部存储对象,所处被抛出的对象叶欢给操作系统了,throw会初始化一个抛出特殊的异常对象副本(匿名对象),异常对象由编译管理,对象传给对应的catch处理后撤销。
栈展开
- 抛出异常的时候,暂停当前函数的执行,开始查找对应的匹配catch。
- 首先在throw本身是否在团员块内部,如果是查找catch,如果有匹配的,就处理;如果没有匹配的,则退出当前函数栈,继续在调用函数的栈中查找;如果到main函数的栈依旧没有找到匹配的,就终止程序。
异常捕获的匹配规则
-异常对象类型与catch的类型必须完全匹配
例外:
1.从非const对象到const对象。
2.从派生类型到基类类型的转换。
3.数组转换为指向数组的指针,函数转换为指向函数的指针。
#include <iostream> #include <string> using namespace std; class Exception { public : Exception(int errId, const char * errMsg) : _errId(errId ) , _errMsg(errMsg ) {} void What () const { cout<<"errId:" <<_errId<< endl; cout<<"errMsg:" <<_errMsg<< endl; } private : int _errId ; // 错误码 string _errMsg ; // 错误消息 }; void Func1 (bool isThrow) { // ... if (isThrow ) { throw Exception (1, "抛出 Excepton对象" ); } // ... printf("Func1(%d)\n" , isThrow); } void Func2 (bool isThrowString, bool isThrowInt) { // ... if (isThrowString ) { throw string ("抛出 string对象" ); } // ... if(isThrowInt ) { throw 7; } printf("Func2(%d, %d)\n" , isThrowString, isThrowInt ); } void Func () { try { Func1(false ); Func2(true , true); } catch(const string& errMsg) { cout<<"Catch string Object:" <<errMsg<< endl; } catch(int errId) { cout<<"Catch int Object:" <<errId<< endl; } catch(const Exception& e) { e.What (); } catch(...) { cout<<" 未知异常"<< endl; } printf ("Func()\n"); } int main() { Func(); return 0; }
运行结果如下:
异常的重新抛出
有可能单个catch不能完全处理一个异常,在进行一些校正处理后,希望再交给更外层的调用链函数来处理,catch则可以通过重新将异常传递给上层的函数来进行处理。
#include <iostream> #include <string> using namespace std; class Exception { public : Exception(int errId = 0, const char * errMsg = "" ) : _errId(errId ) , _errMsg(errMsg ) {} void What () const { cout<<"errId:" <<_errId<< endl; cout<<"errMsg:" <<_errMsg<< endl; } private : int _errId ; // 错误码 string _errMsg ; // 错误消息 }; void Func1 () { throw string ("Throw Func1 string"); } void Func2 () { try { Func1(); } catch(string & errMsg) { cout<<errMsg <<endl; Exception e (1, "Rethorw Exception"); throw e ; // throw; // throw errMsg; } } void Func3 () { try { Func2(); } catch (Exception & e) { e.What (); } } int main() { Func3(); return 0; }
运行结果如下:
异常 构造函数&析构函数
构造函数完成对象的构造和初始化,要保证不在构造函数中抛出异常,否则可能导致对象不完整或没有完全初始化
析构函数 主要完成资源的清理,保证不在析构函数中抛出异常,否则导致资源泄漏(内存泄漏,句柄未关闭等)。
相关文章推荐
- 深入理解C++异常
- More Effective C++----(12)理解"抛出一个异常"与"传递一个参数"或"调用一个虚函数"间的差异
- C++中理解“传递参数”和异常之间的差异
- C++中的异常捕获与处理:Try、Throw、Catch关键字的理解和使用
- 深入理解C++中的异常处理机制
- 深入理解C++中的异常处理机制
- 深入理解C++中的异常处理机制
- c++异常捕获的通俗理解
- C++中理解“抛出一个异常”与“传递一个参数”或“调用一个虚函数”间的差异(11)---《More Effective C++》
- C与C++中的异常处理3
- C++、Java和C#中的异常处理
- 学习C++(一) 我现在理解的C++
- USB口异常与C++&Java
- 用C++ 而不是 用c (4)使用异常和返回值
- C与C++中的异常处理4
- C++异常处理 http://blog.csdn.net/oury
- 我的理解:在有返回值的函数内是否应该使用异常处理?欢迎大家斧正
- 更深入一点理解switch语句及c/c++对const的处理
- MSN上关于C++的异常处理和名字空间的聊天记录
- 理解Visual C++.NET定制MFC应用程序(三)