• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
demps_c
博客园    首页    新随笔    联系   管理    订阅  订阅
关于异常

所有标准异常归根结底都是从exception类派生而来,此类定义在头文件exception中

两个主要的派生类为logic_error(报告程序逻辑错误,通过检查代码,能够发现这类错误)

和runtime_error(报告运行错误,只有在程序运行时候,这类错误才能被检查到)

这两个类的定义在头文件stdexcept中,通过exception::what()函数,可以从对象中得到他所保存的消息

一般不要从exception派生类,而是从logic_error或者runtime_error派生自己的类

 

 

 

 

class x{
4 public:
5 class a{};
6 class b{};
7 class c{};
8 void f(){throw b();}
9 };
10 void f1(){
11 try{
12 x x1;
13 x1.f();
14 }catch(x::a&){
15 cout << "caught a" << endl;
16 }catch(x::b&){
17 cout << "caught b" << endl;
18 }catch(x::c&){
19 cout << "caught c " << endl;
20 }
21 }

 

在catch语句里面的重新抛出异常使用throw;(仅仅是throw后面一个分号)并且此异常不会被随后的catch捕捉到,而是抛出到更高一层语境中的异常处理器(catch语句)

 

如果没有任何一个异常处理器能捕捉到某个异常,则系统会自动调用terminate函数(可以使用set_terminate设置此函数)

 

构造函数没有正常结束时候,不会调用析构函数

class a{
23 public:
24 a(){
25 value ++;
26 cout << "constructor" << value << endl;
27
28 if(3 == value){
29 throw 3;
30 }
31 }
32 ~a(){cout << "destructor" <<value << endl;}
33 private:
34 static int value;
35 };
36 int a::value = 0;
37 void f2(){
38 try{
39 a a1;
40 a a2[5];
41 a a3;
42 }catch(int i){
43 cout << "end" <<  i <<endl;
44 }
45 }

结果是

constructor1
constructor2
constructor3
destructor3
destructor3
end 3

因为第三个对象(a2[1])构造函数抛出异常,也就是非正常结束了,所以就会导致析构函数不执行

然后捕捉到的值是那个抛出的对象(也就是3),如果前面抛出了10000,end 后面就是10000

(记住:如果一个对象的构造函数在执行过程中抛出异常,那么这个对象的构造函数就不会被调用)这个可能会对象的一部分内存分配成功,一部分失败,或者内存分配成功,但是析构函数没有执行,没有释放内存(delete)

一般呢,防止资源泄露有两个方式

1 在构造函数中捕获异常,用于释放资源

2 在对象的构造函数中分配资源,并且在对象的析构函数中释放资源

 

 

class x{

public:

  x(int i){}

};

class y{

  public:

    y(int i):try x(i){}catch(x& x1){

      cout << "shit" << endl;

    }

};

 

 

class a{
5 public:
6 a(int i){}
7 };
8
9 class b{
10 public:
11 b(){}
12 };
13 void f2()throw(a,b);有可能抛出a,b两个类型的异常
14 void f3();可能抛出任何类型的异常
15 void f4()throw();不可能抛出任何类型的异常

如果函数所抛出的异常没有列在异常规格说明集中,一个特殊的函数unexpected()将会被调用,默认的unexpected会调用前面的terminate函数

也可以使用set_unexpected设置此类函数

 

posted on 2013-10-03 09:45  demps_c  阅读(170)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3