错误与异常处理入门

C++错误与异常处理

   概念:

      1.错误:分为编译时的错误和运行时的错误。

             ①编译时的错误:编译时的错误主要是语法错误,比如:句尾没有加分号,括号不匹配,关键字错误等,这类错误比较容易修改,因为编译系统会指出错误在第几行,什么错误。

             ② 运行时的错误: 运行时的错误则不容易修改,因为其中的错误是不可预料的,或者可以预料但无法避免的,比如内存空间不够,或者在调用函数时,出现数组越界等错误。

              如果对于这些错误没有采取有效的防范措施,那么往往会得不到正确的运行结果,程序不正常终止或严重的会出现死机现象。我们把程序运行时的错误统称为异常,对异常处理称为异常处理。C++中所提供的异常处理机制结构清晰,在一定程度上可以保证程序的健壮性。

     异常处理:

       C++中处理异常的过程是这样的:在执行程序发生异常,可以不在本函数中处理,而是抛出一个错误信息,把它传递给上一级的函数来解决,上一级解决不了,再传给其上一级,由其上一级处理。如此逐级上传,直到最高一级还无法处理的话,运行系统会自动调用系统函数terminate,由它调用abort终止程序。这样的异常处理方法使得异常引发和处理机制分离,而不在同一个函数中处理。这使得底层函数只需要解决实际的任务,而不必过多考虑对异常的处理,而把异常处理的任务交给上一层函数去处理。

            

             C++的异常处理机制有3部分组成:try(检查),throw(抛出),catch(捕获)。把需要检查的语句放在try模块中,检查语句发生错误,throw抛出异常,发出错误信息,由catch来捕获异常信息,并加以处理。一般throw抛出的异常要和catch所捕获的异常类型所匹配。异常处理的一般格式为:

  try

  {

    被检查语句

    throw 异常

  }

  catch(异常类型1)

  {

    进行异常处理的语句1

  }

  catch(异常类型2)

  {

    进行异常处理的语句2

  }

  ...

直接上代码吧:


# if 1
# include <iostream>
using namespace std;

void f(int n)
{
	cout<<"进入函数g,n = "<<n<<endl;
	try
	{
		if(n == 1)
		{
			throw 1;//抛出Int类型异常
		}
		if(n == 2)
		{
			throw 2.1;//抛出double类型异常
		}
		if(n == 3)
		{
			throw "abc";//抛出字符串类型异常
		}
	}

	catch(char *)
	{
		cout<<"捕获字符串类型的异常!"<<endl;
	}
	cout<<"退出函数f,n = "<<n<<endl;
}


void g(int n)
{
	cout<<"进入函数g,n = "<<n<<endl;
	try
	{
		f(n);
	}

	catch(double)
	{
		cout<<"捕获double类型的异常!"<<endl;
	}
	cout<<"退出函数g,n = "<<n<<endl;
}

int main()
{
	for(int i = 3; i > 0; i--)
	{
		try
		{
			g(i);
		}
		catch(int)
		{
			cout<<"捕获int类型的异常!"<<endl;
		}
		cout<<endl;
	}
	return 0;
}
/*
<pre name="code" class="cpp">(vs 2012)<span style="font-family: Arial, Helvetica, sans-serif;">运行结果:</span>

 

进入函数g,n = 3
进入函数g,n = 3
捕获字符串类型的异常!
退出函数f,n = 3
退出函数g,n = 3

进入函数g,n = 2
进入函数g,n = 2
捕获double类型的异常!
退出函数g,n = 2

进入函数g,n = 1
进入函数g,n = 1
捕获int类型的异常!

请按任意键继续. . .
*/
# endif


# if 1
# include <iostream>
using namespace std;

void fun1(bool flag)
{
	if(flag)
	{
		throw 1;
	}
}

void fun2(bool flag)
{
	if(flag)
	{
		throw 'c';
	}
}

void fun3(bool flag)
{
	if(flag)
	{
		throw "abc";
	}
}

class CMyExcept{
public:
	void display()
	{
		cout<<"自定义异常类"<<endl;
	}
};

void fun4(bool flag)
{
	if(flag)
	{
		throw CMyExcept();
	}
}

void usage()
{
	const char* str ="1 抛出整数类型异常\n2 抛出字符类型异常\n3 抛出字符串类型异常\n4 抛出自定义类型异常\n0 退出循环\n";
	cout<<str<<endl;
}

int main()
{
	usage();
	bool flag = false;
	while(!flag)
	{
		int select;
		cin>>select;
		try
		{
			if(0 == select)
			{
				flag = true;
			}
				fun1(select == 1);
			    fun2(select == 2);
			    fun3(select == 3);
			    fun4(select == 4);
		}

		catch(int i)
		{
			cout<<"捕获到整数类型异常,根据为: ";
			cout<<i<<endl;
		}

		catch(char c)
		{
			cout<<"捕获到字符类型异常,根据为: ";
			cout<<c<<endl;
		}

		catch(char *str)
		{
			cout<<"捕获到字符串类型异常,根据为: ";
			cout<<str<<endl;
		}

		catch(CMyExcept &e)
		{
			cout<<"捕获到自定义类型异常,根据为: ";
			e.display();
		}
	}
	return 0;
}
/*
(vs 2012)运行结果:

1 抛出整数类型异常
2 抛出字符类型异常
3 抛出字符串类型异常
4 抛出自定义类型异常
0 退出循环

1
捕获到整数类型异常,根据为: 1
2
捕获到字符类型异常,根据为: c
3
捕获到字符串类型异常,根据为: abc
4
捕获到自定义类型异常,根据为: 自定义异常类
0
请按任意键继续. . .
*/
# endif

补充:1.try 和 catch的花括号{}不能省略。
      2.一个try可以和多个catch进行匹配,以便满足不同类型异常的处理。
      3.catch(...){} 可以捕获任意类型的异常。
      4.如果throw内无任何语句,表示它将异常重新抛出原来的异常,交由上一层的catch进行处理。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值