C++里为什么要用异常处理try和catch

本文通过实例演示了C++异常处理的基本用法,包括try-catch语句的应用,并探讨了为何选择异常处理而非简单的if-else判断。文章还讨论了异常处理如何提高代码的复用性和简化程序结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文介绍异常处理的正确使用,以及异常处理的创建和创建的理由

一、误解没有捕获到异常

       很多文章对异常处理的解释大概是这样的:人们设计出来的程序,做不到天衣无缝,在运行时总会出现各种意想不到的异常。因此,希望程序不仅能在正确的情况下正常运行,而且在程序有错误的情况下也能作出相应的处理,而不致使程序莫名其妙的终止崩溃,甚至出现死机的现象。比如做除法时分母遇到0,访问到了非法指针。

     但有很多初学者(比如我)发现,虽然使用了异常处理,但程序依然崩溃,抱怨没有捕获到异常。调试的时候还是会弹出下面这个窗口:


       其实这不是崩溃,只是一个遇到异常的提示,如果我们做了异常处理,那么直接点击continue就可以了,你会发现程序可以继续执行下去。并且,我们直接运行生成的exe文件,也是正常执行。这就是异常处理的好处。

二、异常处理的创建

      下面给出C++异常处理语句try--catch的一般使用的演示代码,以做除法下分母为0为例。

#include "stdafx.h"
#include<iostream>
using namespace std;
double divide(double a, double b)
{
	if (b == 0)
	{
		throw b;
		return 0;
	}
	return a / b;
}

int main()
{
	double a=3, b=0;
	try
	{
		divide(a,b);
	}
	catch (double b)
	{
		cout << "exception is caught!";
	}
	return 0;
}

       可以看到,定义的divide函数中有一个抛出异常的语句:throw b;这里就自定义了一个异常,所以我说这是异常处理的创建。

        一些语法规则:

  •  要把可能出现异常的,要检查的语句放在try后面的花括号中,或者说有throw关键字抛出异常的程序段。
  • 异常信息提供给try-catch语句结构,系统会去寻找与try匹配的catch语句,try和catch是成对出现的,类似if和else。
  • 异常抛出后,程序就跳到了catch语句中。
  • 被检测的部分必须用try括起来,要不然throw抛出的异常不起作用。
  • catch和try后面执行的语句都必须用花括号包含,即使只有一条语句。在两者之间不得插入其他语句。
  • 可以只有try而没有catch。
  • catch后面的参数,一般是一个抛出异常的类型就可以了。"..."删节号表示所有类型。

三、为什么要创建自己的异常处理

       其实我们用if和else也可以,那么为什么我不直接用if和else就可以了,在用if(b==0)来判断到分母为0的情况下,直接做一些处理,比如打印出“警告:分母为0!”这样的报错信息,程序依然不会崩溃,代码简单,逻辑也清晰呀。为什么要使用throw抛出一个异常,然后又在其他地方用catch接收这个异常,再做处理呢?这样写,不是更显得复杂了吗?而且相对if和else,抛出异常的方式的处理速度也相对较慢吧?再者也显得不直观,当检测到异常时,还要跑到别的地方看看是如何处理这个异常的。

        这里根据谭浩强的讲解和我自己所认识,我给出一些要使用异常处理语句的理由:

1、异常处理机制体现了面对对象程序设计的思想。我们还是以除法这个例子,对于分母为0这个特例的处理。假如我们只用if--else语句,逻辑上确实可以保证程序正常运行。但是,异常处理的方式就被固定了,比如处理方式是打印出“警告:分母为0”这样的一个警告,那么所有调用我divide这个函数的程序,在遇到分母为0这种异常的情况下,处理方式都是打印出“警告:分母为0”。这是不是很不符合面向对象的代码重用思想?因为你设计出来的这个divide函数是不可能被他人使用的了的。比如我想设计一个已知路程和时间,求平均速度的程序,那么我遇到输入的时间为0时,我想弹出异常警告为:“时间长度不能为0!”。那么显然你设计的divide函数我就用不上了。但如果divide函数是抛出一个异常,我就可以接收这个异常并用我自己的方式去处理它。

2、减少代码冗余,使程序更简洁。从理由1中可以看到,我们可以重用函数divide,就意味着减少冗余的代码。或者你可能还会质问,如果我在调用divide函数之前,做分母是否为0的判断,那么依然可以正确的调用divide函数,在遇到分母为0的情况,就不调用divide函数,而是打印出自己想要的报错信息或者处理方式。可以告诉你,显然这样会增加工作量,因为每次你调用divide函数时,都要做一个异常判断,我们在实例中的异常判断很简单,只是if(b==0)就可以了,但其他的一些复杂的逻辑,可能要用到大量的代码去检查出异常。如果每次调用divide这样一个函数,我们都要做一次异常判断,那岂不是使得程序很复杂冗余?divide函数是不是设计的很不合理?

3、一般情况下,如果项目不是很大,或者说我们设计出来的方法不会被用于各种场合,那么直接使用C++自带的异常处理就可以了,把可能发生错误的代码段放入try中,然后catch中做相应处理。这是我个人认为,极端的假设,如果程序很小,if和else更有优势,因为没有涉及到代码重用的情况下,try--catch根本没有它们发挥的地方。以上讲的不好的地方,希望大家指出,互相学习。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值