C++之try catch 异常处理入门实例

所属分类: 软件编程 / C 语言 阅读数: 89
收藏 0 赞 0 分享

在程序设计过程中,我们总是希望自己设计的程序是天衣无缝的,但这几乎又是不可能的。即使程序编译通过,同时也实现了所需要的功能,也并不代表程序就已经完美无缺了,因为运行程序时还可能会遇到异常,例如当我们设计一个为用户计算除法的程序时,用户很有可能会将除数输入为零,又例如当我们需要打开一个文件的时候确发现该文件已经被删除了……类似的这种情况很有很多,针对这些特殊的情况,不加以防范是不行的。

我们通常希望自己编写的程序能够在异常的情况下也能作出相应的处理,而不至于程序莫名其妙地中断或者中止运行了。在设计程序时应充分考虑各种异常情况,并加以处理。

在C++中,一个函数能够检测出异常并且将异常返回,这种机制称为抛出异常。当抛出异常后,函数调用者捕获到该异常,并对该异常进行处理,我们称之为异常捕获。

C++新增throw关键字用于抛出异常,新增catch关键字用于捕获异常,新增try关键字尝试捕获异常。通常将尝试捕获的语句放在 try{ } 程序块中,而将异常处理语句置于 catch{ } 语句块中。

异常处理的基本语法如下所述。首先说一下抛出异常的基本语法:
throw 表达式;
抛出异常由throw关键字加上一个表达式构成。抛出异常后需要捕获异常以及异常处理程序,其基本语法如下:
try
{
//可能抛出异常的语句
}
catch (异常类型1)
{
//异常类型1的处理程序
}
catch (异常类型2)
{
//异常类型2的处理程序
}
// ……
catch (异常类型n)
{
//异常类型n的处理程序
}

由try程序块捕获throw抛出的异常,然后依据异常类型运行catch程序块中的异常处理程。catch程序块顺序可以是任意的,不过均需要放在try程序块之后。

[例1] C++异常处理示例:

#include<iostream>
using namespace std;
enum index{underflow, overflow};
int array_index(int *A, int n, int index);
int main()
{
  int *A = new int[10];
  for(int i=0; i<10; i++)
    A[i] = i;
  try
  {
    cout<<array_index(A,10,5)<<endl;
    cout<<array_index(A,10,-1)<<endl;
    cout<<array_index(A,10,15)<<endl;
  }
  catch(index e)
  {
    if(e == underflow)
    {
      cout<<"index underflow!"<<endl;
      exit(-1);
    }
    if(e == overflow)
    {
      cout<<"index overflow!"<<endl;
      exit(-1);
    }
  }
  return 0;
}
int array_index(int *A, int n, int index)
{
  if(index < 0) throw underflow;
  if(index > n-1) throw overflow;
  return A[index];
}

本例展示了一个数组越界的异常捕获程序。array_index函数用于返回数组index下标的数值,如果出现异常则抛出异常。try程序块中的程序语句为可能出现异常情况的语句,catch则为针对异常的处理语句。在程序一开始我们定义了一个全局的枚举类型变量index,并且定义了两个值,分别为underflow和overflow,这两个值作为抛出异常的返回值。当在主函数要求输出越界的数组值时,调用array_index函数,一旦有预定异常抛出,则通过try捕获并根据catch语句针对异常情况作出处理。

在前面我们介绍了new和delete动态分配内存操作符,如果new或new[]不能成功分配所请求的,将会抛出一个bad_alloc异常。在使用new或new[]操作符分配动态内存,可以通过如下方式检测并捕获存储空间分配失败的异常。

[例2] 捕获new、new[] 抛出的异常:

int * p;
try
{
  p = new int[10];
}
catch(bad_alloc)
{
  cerr<<"allocate failure!"<<endl;
  exit(-1);
}

在C语言中,异常通常是通过函数返回值获得,但这样一来,函数是否产生异常则需要通过检测函数的返回值才能得知。而在C++中,当函数抛出一个返回值时,即使不用try和catch语句,异常还是会被处理的,系统会自动调用默认处理函数unexpected来执行。

下面是其他网友的补充

#include <exception> 
#include <iostream> 
using namespace std; 
 
/********************************** 
//project -> Properties -> C/C++ -> Code Generation --> Enable C++ Exceptions 
//选择 Yes with SEH Exceptions (/EHa) 这样的话C++的try catch 也可以捕获到空指针,内存越界,0除异常 
//默认是选择Yes (/EHsc) 
**********************************/ 
 
void TestIntType() 
{ 
  try 
  { 
    throw 1; 
  } 
  catch(...) 
  { 
    cout<< "在 try block 中, 准备抛出一个异常." << endl; 
  } 
} 
 
void TestDoubleType() 
{ 
  try 
  { 
    throw 0.5; 
  } 
  catch(...) 
  { 
    cout<< "在 try block 中, 准备抛出一个异常." << endl; 
  } 
} 
 
void TestEmptyPointType() 
{ 
  try 
  { 
    int* p = NULL; 
    *p = 3; 
  } 
  catch(...) 
  { 
    cout<< "非法地址操作异常" << endl; 
  } 
} 
 
void TestDivZeroType() 
{ 
  try 
  { 
    int b = 0; 
    int a = 3/b; 
  } 
  catch(...) 
  { 
    cout<< "0除异常" << endl; 
  } 
} 
 
void TestMemoryOutType() 
{ 
  int * a = new int[4]; 
  try 
  { 
    for (int i = 0; i<245; i++) 
    { 
      a++; 
    } 
    *a = 3; 
  } 
  catch(...) 
  { 
    cout<< "内存越界异常" << endl; 
  } 
} 
 
int main(int argc, char* argv[]) 
{ 
  TestEmptyPointType(); 
  //TestDivZeroType(); 
  TestMemoryOutType(); 
  return 1; 
}

这篇文章就介绍到这,希望大家以后多多支持脚本之家。

更多精彩内容其他人还在看

C++中四种对象生存期和作用域以及static的用法总结分析

以下是对C++中四种对象生存期和作用域以及static的用法进行了详细的介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C++嵌套类与局部类详细解析

从作用域的角度看,嵌套类被隐藏在外围类之中,该类名只能在外围类中使用。如果在外围类之外的作用域使用该类名时,需要加名字限定
收藏 0 赞 0 分享

C++空类详解

以下是对C++中的空类进行了详细的介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C++之友元:友元函数和友元类详解

友元是一种允许非类成员函数访问类的非公有成员的一种机制。可以把一个函数指定为类的友元,也可以把整个类指定为另一个类的友元
收藏 0 赞 0 分享

C++中返回指向函数的指针示例

int (*ff(int)) (int *,int);表示:ff(int)是一个函数,带有一个int型的形参,该函数返回int (*) (int *,int),它是一个指向函数的指针,所指向的函数返回int型并带有两个分别是Int*和int型的形参
收藏 0 赞 0 分享

C数据结构之单链表详细示例分析

以下是对C语言中的单链表进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C数据结构之双链表详细示例分析

以下是对c语言中的双链表进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

浅析如何在c语言中调用Linux脚本

如何在c语言中调用Linux脚本呢?下面小编就为大家详细的介绍一下吧!需要的朋友可以过来参考下
收藏 0 赞 0 分享

深入解析unsigned int 和 int

以下是对unsigned int和int进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

浅谈C++中的string 类型占几个字节

本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节
收藏 0 赞 0 分享
查看更多