异常处理(throw,try, catch)

异常处理的意思是说当次模块产生错误时,此模块并不处理,而是抛给此模块的调用者来处理

异常处理的语法:

-- 抛掷异常的程序段: 

    throw 表达式

-- 捕获并处理异常的程序段

    try

       复合语句          (保护段)

    catch(异常声明)

        复合语句            (异常处理程序)

    catch(异常声明)

        复合语句

** 若有异常则通过throw创建一个异常对象并抛掷

** 将可能抛出异常的程序段嵌在try块之中,通过正常的顺序执行到达try语句,然后执行try块内的保护段

** 如果在保护段执行期间没有引起异常,那么跟在try块后的catch子句就不执行。程序从try块后的最后一个catch子句后面的语句继续执行

** catch子句按其在try块后出现的顺序被检查,匹配的catch子句将捕获并处理异常(或继续抛掷异常)

** 如果匹配的处理器未找到,则库函数terminate将被自动调用,其缺默认能是调用abort终止程序 

例子:

#include <iostream>

using namespace std;

int divide(int x, int y){
	if (y ==0 ){
		throw x;
	}
	return x/y;
}
int main(){
	try{
		cout << "5/2 = " << divide(5, 2)<< endl;
		cout << "8/0 = " << divide(8, 0)<< endl;
		cout << "7/1 = " << divide(7, 1)<< endl;
	} catch (int e){
		cout << e << " is divided by zero! " <<endl;
	}
	cout<< "That is ok." <<endl;
	return 0;
}

运行结果:

异常接口声明:

-- 一个函数显示声明可能抛出的异常,有利于函数的调用者为异常处理做好准备

** 可以在函数的声明中列出这个函数可能抛掷的所有异常类型

    例如:void fun() throw(A, B, C, D);

** 若无异常接口声明,则此函数可以抛掷任何类型的异常

** 不抛掷任何类型异常的函数声明如下:

        void fun() throw();

异常处理中的构造与析构:

自动的析构:

-- 找到一个匹配的catch异常处理后

    * 初始化异常参数

    * 将从对应的try块开始到异常被抛掷处之间构造(且尚未析构)的所有自动对象进行析构

    * 从最后一个catch处理之后开始恢复执行

例子:

#include <iostream>
#include <string>

using namespace std;

class MyException{
public:
	MyException(const string &message) : message(message) {}
	~MyException() {}
	const string &getMessage() const { return message;}
private:
	string message;
};

class Demo{
public:
	Demo(){cout << "Constructor of Demo" << endl;}
	~Demo() {cout << "Destructor of Demo" << endl;}
};

void func() throw(MyException) {
	Demo d;
	cout << "Throw MyException in func()" <<endl;
	throw MyException("exception thrown by func()");
}

int main(){
	cout << "In main function" <<endl;
	try{
		func();
	}
	catch(MyException & e){
		cout <<" Caught an exception: " << e.getMessage() <<endl;
	}

	cout << "Resume the execution of main()" <<endl;
	return 0;
}

运行结果:

从运行结果中可以看出,当异常抛出的时候,创建的对象会自动析构掉

标准程序库异常处理:

标准异常类的基础:

exception:标准程序库异常类的公共基类

logic_error:表示可以在程序中被预先检测到的异常

    * 如果小心地编写程序,这类异常能够避免

runtime_error表示难以被预先检测的异常

例子:

#include <iostream>
#include <cmath>
#include <stdexcept>

using namespace std;

double area(double a, double b, double c) throw(invalid_argument)
{
	if(a <= 0 || b <= 0 || c<= 0)
		throw invalid_argument(" the side length should be postive");
	if(a+b <= c || b+c <= a || c+a <= b)
		throw invalid_argument (" the side length should fit yje triangle inequation");

	double s = (a+b+c)/2;
	return sqrt(s*(s-a)*(s-b)*(s-c));
}

int main(){
	double a, b, c;
	cout << "Please input the side lengths of a triangle: ";
	cin >> a >> b >>c;
	try {
		double s = area(a, b, c);
		cout<< "Area: "<< s <<endl;
	} catch (exception &e){
		cout << "Error: " << e.what() <<endl;
	}
	return 0;
}

运行结果:

猜你喜欢

转载自blog.csdn.net/weixin_42380877/article/details/81272629