在异常处理中处理析构函数

一个例子:
#include<iostream>
#include<string>
using namespace std;
class Student
{
	public:
		Student(int n,string nam)
		{
			num=n;
			name=nam; 
			cout<<"constructor-->"<<num<<endl;
		}
		~Student()
		{
			cout<<"destructor-->"<<num<<endl; 
		}
		void get_data();
	private:
		int num;
		string name;
};
void Student::get_data()
{
	if(num==0)throw num;		//当num=0的时候,将int型变量num抛出
	else cout<<num<<" "<<name<<endl;//当num≠0的时候,输出num和name
	cout<<"in get_data()"<<endl; 	//输出信息,表示目前在get_data中 
} 
void fun()
{
	Student stud1(1,"Tan");
	stud1.get_data();
	cout<<"\n============分割线呼啸而过======================\n"<<endl; 
	Student stud2(0,"Li");
	stud2.get_data();
} 
int main()
{
	cout<<"main begin"<<endl;
	cout<<"call fun()"<<endl;
	try
	{
		fun(); 
	} 
	catch(int n)
	{
		cout<<"num="<<n<<",error!"<<endl; 
	}
	cout<<"main end"<<endl;
	return 0; 
} 

输出结果:
/*
	main begin
	call fun()
	constructor-->1
	1 Tan
	in get_data()
	
	============分割线呼啸而过======================
	
	constructor-->0
	destructor-->0
	destructor-->1
	num=0,error!
	main end
*/

分析:函数fun中,当执行到stud2.get_data()的时候,get_data函数抛出异常,因为get_data函数中没够catch结果,所以无法捕捉异常,只能像上级传递,返回到了fun函数中。在fun中也没有catch结构,所以就又返回到了main函数中。因为stud1和stud2实在fun函数中定义的,所以当异常从catch返回到main函数的时候,这两个对象的生命周期已经结束,所以按照“先构造的对象后析构”的原则进行析构,所以输出destructor-->0和destructor->1。然后等到了main函数中,发现有与之匹配的catch函数,所以执行执行异常操作,然后继续执行异常操作之后的语句。

从这个例子还可以看出,我们抛出异常的位置一般位于函数体的首部,在函数体中首先进行检验,发现有异常就立即抛出,因为它继续执行函数体中的接下来的语句是没有意义的。

posted @ 2013-12-14 10:07  千手宇智波  阅读(283)  评论(0编辑  收藏  举报