c++异常处理和RTTI

RTTI(Run-timeType Identification)

1.异常处理的原理

传统的错误处理是用不同的数值来表示不同类型的错误,其表达能力很有限,因为:一个数字包含的信息量人少。C++异常处理机制将异常类型化,显然一个类型要比 一个数字包含的信息量大得多。
比如我们常用的函数fopen(),当打开文件失败时返回 NULL。按照传统的错误处理方法,在调用fopen()后立即检查其返回值,
如果为 NULL 就进行错误处理。但是如果将返回 NULL 改为抛出异常 OpenFaied,那么我们就不用在调用 fopen()后马上检查返回值,而是在调用函数内部或者更高层的调用者那里设置异常处理器来捕获这个异常。C++保证:如果一个异常在抛出点没有得到处理,那么它将一直被抛向上层调用者,直至 main0西数,直到找到一个类型匹配的异常处理器,否则调用 terninate()结朿程序。
可以看出:异常处理机制实际上是一种运行时通知机制。经典例子:

class DevidedByZero //异常类
{
public:
DevidedByZero(const char* p);
const char* description();

private:
char* desp;

};

double Devide(double a, double b)
{
	if(abs(b)<std::numeric_limits<double>::epsilon())
	{
		throw DevidedByZero(); //提前检测异常发生的条件并抛出自定义异常(这里抛出类DevidedByZero的一个对象)
	}
	return a / b;
}

void test()
{
	double x = 100, y = 20.5;
	try
	{
		cout << Devide(x,y) << endl; //可能抛出异常DevidedbyZero
	}
	catch(const DevidedByZero& ex) //前面抛出类对象,接受以引用方式返回
	{
		cerr <<ex.description() << endl;
	}
}

因此当异常抛出时,真正的错误实际上并未发生!

2.异常类型和异常对象

任何一种类型都可以当做异常类型,因此任何一个对象都可以当作异常对象,包括基本数据类型的变量、常量、任何类型的指针、引用、结构等,甚至空结构或空类对象。
但我们不会直接使用基本数据类型对象作为异常,因为它们表示异常类的能力不足,而自定义异常类可以具体描述我们需要的异常类型。

3.异常处理的语法结构

异常处理也是一种程序控制结构,throw只是一条语句,而try和catch各自引导着一个程序块。try{ }块包含了可能会有异常抛出的代码段,而catch{ }块则包含用户定义的异常处理代码,即异常处理器(handler)。一条throw语句只能抛出一个异常,一个catch子句也只能捕获一种异常。需要注意的是:异常抛出点常常和异常捕获点距离很远,异常抛出点可能深埋在底层软件模块内,而异常捕获点常常在高层组件中;异常捕获却必须和异常提炼(try块)结合使用,并且可以通过异常组合在一个地点捕获多种异常

一个catch()子句就相当于带有一个参数的函数,而throw语句相当于函数调用语句。虽然如此,但行为并非完全像一个函数一样。catch处理完后不会返回到throw语句那里,要么退出要么继续执行,因此更像一个goto语句。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值