C++异常(try、throw、catch) 快速掌握

使用形式如下:

try //使用try标识下面代码段抛出的异常将会由catch语句处理
{
	throw "some error occur"; //使用throw抛出异常
}
catch (const char* e) //catch 语句匹配异常的数据类型,并执行对应处理
{ 
	std::cout << e <<std::endl; //此处输出:some error occur
}
catch (int) //可有多个catch匹配不同类型的错误;形参名(如上面的e)可省略
{

}

try

try顾名思义就是要尝试执行下面的语句,如果有抛出错误可以通过catch来处理。没有try就无法用catch

throw

throw代表抛出异常,其后面可以跟随各种内置或自定义类型,如果是自定义的类要确保其复制/移动构造函数和析构函数可以访问,因为异常处理过程中会发生对象的复制或移动。

除了直接在try语句块中throw外,调用的函数内也可以throw。如:

int divide(int x, int y)
{
	if (y == 0) throw "divide 0 error";

	return x / y;
}

int main()
{
	try 
	{
		divide(1, 0); // try中调用函数,函数内throw
	}
	catch (const char* e) 
	{
		std::cout << e <<std::endl; // 此处输出:divide 0 error
	}
}

C++ 在throw后会一直向函数上层寻找try catch,若到main之后还没找到就会中断程序。

若不希望函数向上抛出异常,可以在函数的声明和定义中增加noexcept关键字,如void func() noexcept,这会阻断异常传播,转而直接调用std::terminate终止程序。增加此关键词也可以使得编译器做更多优化。

这套异常机制也只能处理手动throw出来的错误,对于原有的段错误、除0错误之类还会像原来一样直接终止程序。需要自己像上面的divide函数那样添加检查和抛出的逻辑。不过标准库中已经实现了很多相关的抛出逻辑了。

catch

trythrow异常后,程序会从上到下挨个尝试匹配catch语句中的错误类型,匹配成功则执行其中的代码并不再执行后续的catch语句。

匹配成功主要的标准是:

  • catch中的类型与抛出的异常类型相同
  • catch中类型是抛出的异常类型的父类

在该标准的基础上,允许catch中增加额外的constvolatile修饰(但不允许减少修饰);允许catch中使用引用。

除此之外可以用catch(...)匹配任意类型。

举例来说,下面的几个catch都可以匹配成功:

struct A // 定义父类
{
};
struct B: public A // 定义子类
{
};

int main()
{
	try 
	{
		B b;
		throw b; 
	}
	catch (const A& e)  // 父类引用捕获
	{
		std::cout << "Base's reference" <<std::endl;
	}
	catch (volatile B e) // 子类捕获
	{
		std::cout << "Same class" << std::endl;
	}
	catch (...) // 全捕获
	{
		std::cout << "All exception"<< std::endl;
	}

	return 0;
}

不过由于找到第一个匹配的catch后就不会继续看剩余的catch了,所以这里的volatile B e实际上永远不会用上,被上方的父类匹配屏蔽了。

在catch语句中,还可以单用一个throw重新抛出异常给上层处理:

try
{
	try 
	{
		throw "err";  // 抛出异常
	}
	catch (const char* e) // 内层捕获异常
	{
		std::cout << "Inner " << e << std::endl;
		throw;  // 重新抛出异常
	}
	catch (...) // 重新抛出也不会进入此catch,而是外层的catch。
	{
		std::cout << "All" << std::endl;
	}
}
catch (const char* e) // 外层捕获异常
{
	std::cout << "Outter " << e << std::endl;
}
/* 输出:
Inner err
Outter err
*/

参考资料

https://www.tutorialspoint.com/cplusplus/cpp_exceptions_handling.htm#:~:text=A%20C%2B%2B%20exception%20is%20a,try%2C%20catch%2C%20and%20throw.
https://en.cppreference.com/w/cpp/language/try_catch

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值