好久没看C++了,今天抽空看了看C++里的异常处理,总的来说是在会发生异常的函数中通过throw抛出一个对象(可以是自定义的任何对象,也可以是int,char这些语言内置的基本对象,这点与java不同,java一定要是Exception的子对象),然后在主函数中通过try/catch来捕抓异常并且处理异常,java的异常处理也是如此。
下面举出一个例子说明:
istack.h // 定义一个栈类
#ifndef _ISTACK_
# define _ISTACK_
# include
using std::vector;
#endif
class iStack
{
public:
iStack(int capacity):stack(capacity),top(0){};
void pop(int& value);
void push(int value);
bool full();
bool empty();
private:
int top;
vectorstack;
};
exception.h //定义2个异常类
#ifndef _EXCEPTION_H
#define _EXCEPTION_H
# include
using std::cerr;
using std::endl;
#endif
class poponEmpty
{
public:
poponEmpty(){};
inline void display()
{
cerr<<"error,the stack has been empty!"< }
};
class pushonFull
{
public:
pushonFull(int pushvalue):value(pushvalue)
{};
inline void display()
{
cerr<<"error,the stack has been full!"< cerr<<"the element which should been added is"< }
private:
int value;
};
istack.cpp
#include "istack.h"
#include "exception.h"
void iStack::pop(int& value)
{ if(empty())
throw poponEmpty(); //栈空抛异常
else
{ top--;
value=stack[top];
}
}
void iStack::push(int value)
{
if(full())
throw pushonFull(value); //栈满抛异常
else
{
stack[top]=value;
top++;
}
}
bool iStack::empty()
{ if (top==0)
return true;
else
return false;
}
bool iStack::full()
{
if(top==stack.size())
return true;
else
return false;
}
main.cpp
#include "stdafx.h"
#include "istack.h"
#include "exception.h"
#include
using namespace std;
int _tmain(int argc, _TCHAR* argv[]) //主函数
{
iStack Stack (2);
try
{
Stack.push(1);
Stack.push(2);
int value;
Stack.pop(value);
cout< Stack.pop(value);
cout< Stack.pop(value);
cout< }
catch (pushonFull& e) //捕抓异常
{
e.display(); //处理异常
}
catch(poponEmpty& e)
{
e.display();
}
return 0;
}
结果;2
1
error,the stack has been empty!
在stl库里的很多函数都有异常处理,所以使用起来都比较安全。
throw语句会新建一个异常对象,catch语句中的异常参数若不是引用,则还会对throw中的异常对象进行拷贝,为了提高效率,catch语句的参数往往是异常对象的引用。
首先在pop函数里面throw一个异常对象,但是pop里面没有try/catch ,所以pop函数带着一个异常退出,控制权交到调用pop函数的main函数中,在该函数中查找该异常对象的catch,依次进行这样的查找,直到找到了该异常对象的catch。若是在最外层的函数中也找不到相应的catch处理,那么程序会自动调用stl库里的terminate,terminate再调用abort进行程序的退出。整个过程叫做栈展开。他会保证整个过程中的局部对象会随着异常抛出而结束。
在catch语句中可以进行rethrow,就是说包含catch的函数对这种异常处理不了,必须交给调用该函数的上一级函数去处理,那就需要在catch{}块内写一条throw即可。
还有一种catch方式是对任何异常进行处理,例如你分配了一些资源,在发生任何异常后需要将资源进行释放,则可以
catch(。。。)
{res.release();}
阅读(624) | 评论(0) | 转发(0) |