C++异常处理

C++异常

  程序有时会遇到运行阶段错误,导致程序无法正常地运行下去。例如,程序可能试图打开一个不可用的文件,请求过多的内存,或者遭遇不能容忍的值。通常程序员都会试图防止这种意外情况。C++异常为处理这种情况提供了一种功能强大而灵活的工具。

处理异常的方法

1、调用abort()

  对于这类问题,处理方式之一是,调用abort()函数。Abort()函数的原型位于头文件cstdlib(或者stdlib.h)中,其典型实现是向标准错误流(即cerr使用的错误流)发送消息abnomal program termination(程序异常终止),然后终止程序。它还返回一个随实现而异的值,告诉操作系统(如果程序是由另一个程序调用的,则告诉父进程),处理失败。程序1是一个使用abort()的小程序。

// error1.cpp -- using the abort() function
#include <iostream>
#include <cstdlib>
double hmean(double a, double b);
int main()
{
	double x, y, z;
	std::cout << "Enter two numbers : ";
	while (std::cin >> x >> y)
	{
		z = hmean(x, y);
		std::cout << "Hamonic mean of "
			<< x << " and " << y << " is " << z << std::endl;
		std::cout << "Enter next set of numbers<q to quit>: ";
	}
	std::cout << "Bye!\n";
	return 0;
}
double hmean(double a, double b)
{
	if (a == -b)
	{
		std::cout << "untenable arguments to hmean()\n";
		std::abort();
	}
	return 2.0 * a * b / (a + b);
}
// 程序清单1中程序的运行情况如下:
/*
Enter two numbers: 3 6
Harmonic mean of 3 and 6 is 4
Enter next set of numbers<q to quit>: 10 -10
untenable arguments to hmean()
abnomal program termination
*/

 注意,在hmean()中调用abort()函数将直接终止程序,而不是先返回到main()。一般而言,显示的程序中断消息随编译器而异。

为了避免异常终止,程序应在调用hmean()函数之前检查xy的值。然而,依靠程序员来执行这种检查是不安全的。

2、返回错误码

  一种比异常终止更灵活的方法是,使用函数的返回值来指出问题。例如,ostream类的get(void)成员通常返回下一个输入字符的ASCII码,但到达文件末尾时,将返回特殊值EOF。对于hmean()来说,这种方法不管用。任何数值都是有效的返回值,因此不可能用于指出问题的特殊值。在这种情况下,可使用指针参数或引用参数来将值返回给调用程序,并使用函数的返回值来指出成功或者失败。通过告知调用程序是成功了还是失败了,使得程序可以采取除异常终止程序之外的其他措施。程序2是一个采用这种方式的实例,它将hmean()的返回值重新定义为bool,让返回值指出成功了还是失败了,另外还给该参数增加了第三个参数,用于提供答案。

//error2.cpp -- returning an error code 
#include<iostream>
#include<cfloat> //(or folat.h) for DBL_MAX
bool hmean(double a, double b, double *ans);
int main()
{
	double x, y, z;
	std::cout << "Enter two numbers: ";
	while (std::cin >> x >> y)
	{
		if (hmean(x, y, &z))
			std::cout << "Harmonic mean of "
			<< x << " and " << y << " is " << z << std::endl;
		else
			std::cout << "one value should not be the negative "
			<< "of the other - try again.\n";
		std::cout << "Enter next set of numbers<q to quit>: ";
	}
	std::cout << "Bye!\n";
	return 0;
}
bool hmean(double a, double b, double *ans)
{
	if (a == -b)
	{
		*ans = DBL_MAX;
		return false;
	}
	else
	{
		*ans = 2.0 * a * b / (a + b);
		return true;
	}
}
// 程序清单2中程序的运行情况如下:
/*
Enter two numbers: 3 6
Harmonic mean of 3 and 6 is 4
Enter next set of numbers<q to quit>: 10 -10
one value should not be the negative of the other - try again.
Enter a new pair of numbers: 1 19
Harmonic mean of 1 and 19 is 1.9
Enter next set of numbers<q to quit>: q
Bye!
*/

  程序说明

  在程序2中,程序设计避免了错误输入导致的恶果,让用户能够继续输入。当然,设计确实依靠用户检查函数的返回值,这项工作是程序员不经常做的。

  第三个参数可以是指针或引用。对内置类型的参数,很多程序员都倾向于使用指针,因为这样可以明显看出是哪个参数用于提供答案。

3、异常机制

  下面介绍如何使用异常机制来处理错误。C++异常是对程序运行过程中发生的异常情况(例如被0除)的一种响应。异常提供了将控制权从程序的一个部分传递到另一个部分的途径。对异常的处理有3个组成部分:

● 引发异常

● 使用处理程序捕获异常

● 使用try块

程序在出现问题时将引发异常。例如可以修改程序清单1中的hmean(),使之引发异常,而不是调用abort()函数。throw语句实际上是跳转,即命令程序调到另一个程序。Throw关键字表示引发异常,紧随其后的值(例如字符串或对象)指出了异常的特征。

程序使用异常处理程序(exception handler)来捕获异常,异常处理程序位于要处理问题的程序中。catch关键字表示捕获异常。处理程序以关键字catch开头,随后是位于括号中的类型声明,它指出了异常处理程序要响应的异常类型;然后是一个用花括号栝起的代码块,指出要采取的措施。catch关键字和异常类型用作标签,指出当异常被引发时,程序应跳到这个位置执行。异常处理程序也被称为catch块。

//error3.cpp -- using an exception
#include<iostream>
double hmean(double a, double b);
int main()
{
	double x, y, z;
	std::cout << "Enter two numbers: ";
	while (std::cin >> x >> y)
	{
		try
		{
			z = hmean(x, y);
		}
		catch (const char *s)
		{
			std::cout << s << std::endl;
			std::cout << "Enter a new pair of numbers: ";
			continue;
		}
		std::cout << "Hamonic mean of " << x << " and " << y
			<< " is " << z << std::endl;
		std::cout << "Enter next set of numbers<q to quit>: ";
	}
	std::cout << "Bye!\n";
	return 0;
}
double hmean(double a, double b)
{
	if (a == -b)
		throw "bad hmean() argument: a = -b not allowed";
	return 2.0 * a * b / (a + b);
}

// 程序清单3中程序的运行情况如下:
/*
Enter two numbers: 3 6
Harmonic mean of 3 and 6 is 4
Enter next set of numbers<q to quit>: 10 -10
bad hmean() aruments: a = -b not allowed
Enter a new pair of numbers: 1 19
Harmonic mean of 1 and 19 is 1.9
Enter next set of numbers<q to quit>: q
Bye!
*/




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值