c++中 try catch throw的基本用法【by徐玉丽】

一、简单的例子

  单刀直入,首先通过一个简单的例子来看基本的用法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<iostream.h>                            //包含头文件
#include<stdlib.h>
double  fuc( double  x,  double  y)                         //定义函数
{
if (y==0)
{
throw  y;                                     //除数为0,抛出异常
}
return  x/y;                                     //否则返回两个数的商
}
void  main()
{
double  res;
try                                             //定义异常
{
res=fuc(2,3);
cout<< "The result of x/y is : " <<res<<endl;
res=fuc(4,0);                                 //出现异常
}
catch ( double )                                     //捕获并处理异常
{
  cerr<< "error of dividing zero.\n" ;
   exit (1);                                     //异常退出程序
  }
}

  catch 的数据类型需要与throw出来的数据类型相匹配的。

  

  二、catch(...)的作用

  catch(…)能够捕获多种数据类型的异常对象,所以它提供给程序员一种对异常对象更好的控制手段,使开发的软件系统有很好的可靠性。因此一个比较有经验的程序员通常会这样组织编写它的代码模块,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void  Func()
{
try
{
     // 这里的程序代码完成真正复杂的计算工作,这些代码在执行过程中
     // 有可能抛出DataType1、DataType2和DataType3类型的异常对象。
}
catch (DataType1& d1)
{
}
catch (DataType2& d2)
{
}
catch (DataType3& d3)
{
}
// 注意上面try block中可能抛出的DataType1、DataType2和DataType3三
// 种类型的异常对象在前面都已经有对应的catch block来处理。但为什么
// 还要在最后再定义一个catch(…) block呢?这就是为了有更好的安全性和
// 可靠性,避免上面的try block抛出了其它未考虑到的异常对象时导致的程
// 序出现意外崩溃的严重后果,而且这在用VC开发的系统上更特别有效,因
// 为catch(…)能捕获系统出现的异常,而系统异常往往令程序员头痛了,现
// 在系统一般都比较复杂,而且由很多人共同开发,一不小心就会导致一个
// 指针变量指向了其它非法区域,结果意外灾难不幸发生了。catch(…)为这种
// 潜在的隐患提供了一种有效的补救措施。
catch (…)
{
}
}

  三、异常中采用面向对象的处理

  首先看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
void  OpenFile(string f)
{
try
{
    // 打开文件的操作,可能抛出FileOpenException
}
catch (FileOpenException& fe)
{
    // 处理这个异常,如果这个异常可以很好的得以恢复,那么处理完毕后函数
    // 正常返回;否则必须重新抛出这个异常,以供上层的调用函数来能再次处
    // 理这个异常对象
    int  result = ReOpenFile(f);
    if  (result ==  false throw ;搜索
}
}
void  ReadFile(File f)
{
try
{
    // 从文件中读数据,可能抛出FileReadException
}
catch (FileReadException& fe)
{
    // 处理这个异常,如果这个异常可以很好的得以恢复,那么处理完毕后函数
    // 正常返回;否则必须重新抛出这个异常,以供上层的调用函数来能再次处
    // 理这个异常对象
    int  result = ReReadFile(f);
    if  (result ==  false throw ;
}
}
void  WriteFile(File f)
{
try
{
     // 往文件中写数据,可能抛出FileWriteException
}
catch (FileWriteException& fe)
{
     // 处理这个异常,如果这个异常可以很好的得以恢复,那么处理完毕后函数
// 正常返回;否则必须重新抛出这个异常,以供上层的调用函数来能再次处理这个异对象
     int  result = ReWriteFile(f);
     if  (result ==  false throw
}
void  Func()
{
try
{
    // 对文件进行操作,可能出现FileWriteException、FileWriteException
    // 和FileWriteException异常
    OpenFile(…);
    ReadFile(…);
    WriteFile(…);
}
// 注意:FileException是FileOpenException、FileReadException和FileWriteException
// 的基类,因此这里定义的catch(FileException& fe)能捕获所有与文件操作失败的异
// 常。
catch (FileException& fe)
{
    ExceptionInfo* ef = fe.GetExceptionInfo();
    cout << “操作文件时出现了不可恢复的错误,原因是:”<< fe << endl;
}
}

  下面是更多面向对象和异常处理结合的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream.h>
class  ExceptionClass
{
     char * name;
public :
     ExceptionClass( const  char * name= "default name"
     {
              cout<< "Construct " <<name<<endl;
              this ->name=name;
     }
    ~ExceptionClass()
     {
              cout<< "Destruct " <<name<<endl;
     }
     void  mythrow()
    {
             throw  ExceptionClass( "my throw" );
    }
}
void  main()
{
        ExceptionClass e( "Test" );
        try
        {
            e.mythrow();
        }  
        catch (...)
       {
          cout<<”*********”<<endl;
        }
}

  这是输出信息:

  Construct Test

  Construct my throw

  Destruct my throw

  ****************

  Destruct my throw   (这里是异常处理空间中对异常类的拷贝的析构)

  Destruct Test

  ======================================

  不过一般来说可能更习惯于把会产生异常的语句和要throw的异常类分成不同的类来写,下面的代码可以是更愿意书写的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class  ExceptionClass
{
public :
     ExceptionClass( const  char * name= "Exception Default Class" )
    {
        cout<< "Exception Class Construct String" <<endl;
    }
    ~ExceptionClass()
    {
       cout<< "Exception Class Destruct String" <<endl;
    }
    void  ReportError()
    {
       cout<< "Exception Class:: This is Report Error Message" <<endl;
    }
};
class  ArguClass
{
    char * name;
public :
    ArguClass( char * name= "default name" )
    {
       cout<< "Construct String::" <<name<<endl;
       this ->name=name;
    }
    ~ArguClass()
    {
       cout<< "Destruct String::" <<name<<endl;
    }
    void  mythrow()
    {
       throw  ExceptionClass( "my throw" );
    }      
};
_tmain()
{
    ArguClass e( "haha" );
    try
    {
      e.mythrow();
    }
    catch ( int )
    {
      cout<< "If This is Message display screen, This is a Error!!" <<endl;   //这行不会执行
    }
    catch (ExceptionClass pTest)
    {
       pTest.ReportError();
    }
    catch (...)
   {
        cout<< "***************" <<endl;  
   }
}

  输出Message:

  Construct String::haha

  Exception Class Construct String

  Exception Class Destruct String

  Exception Class:: This is Report Error Message

  Exception Class Destruct String

  Destruct String::haha

总结:以上为摘抄大神解答,个人理解为catch(object^)表示捕获一个object类型的异常类。而这个类必须是在try语句块中被抛出的。在catch中做异常处理,其中catch(...)为捕获多种类型的异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值