c++面向对象编程———异常

c++面向对象编程———>>>异常

异常是指程序运行期间发生的不正常情况,如new无法获得所需内存、数组下标越界、运算溢出、除0错误、无效参数以及打开文件不存在等。异常处理就是指对程序执行过程中产生的异常进行适当的处理,避免程序出现丢失数据或破坏系统运行等灾难性后果。

1.传统错误处理

1.1 通过函数返回值处理异常

#include <iostream>
#include <cstdio>
using namespace std;
class A{
public:
	A(void){
		cout << "A(void)" << endl;
	}
	~A(){
		cout << "~A()" << endl;
	}
};
int func3(){
	A c;
	FILE *fp = fopen("./a.txt", "r");
	if(fp == NULL){
		return -1;
	}
	cout << "open a.txt successed" << endl;
	fclose(fp);
	return 0;
}
int func2(){
	A b;
	if(func3() == -1)//函数返回值处理异常
		return -1;
	return 0;
}
int func1(void){
	A a;
	if(func2() == -1)//函数返回值处理异常
		return -1;
	return 0;
}
int main(void){
	func1();
	return 0;
}

**优点:**函数调用路径中栈对象得到正确析构,不存在内存泄漏

**缺点:**错误流程处理复杂,代码臃肿

1.2 通过远程跳转处理异常

setjmp
longjmp
if(fp == NULL){
	longjmp(env, -1); //跳转到setjmp位置执行
}


if(setjmp(env) == 0){ //保存当前栈的快照
	func1();
}
else{
	cout << "failed" << endl;
	return -1;
}

**优点:**不需要逐层判断,一步到位,代码精炼

**缺点:**函数调用路径中的栈对象失去析构机会,存在内存泄漏风险

2. C++的异常处理

对传统错误处理作出了改进:发扬优点,避免缺点。

C++引入了3个用于异常处理的关键字:try, throw,catchtry用于检测可能发生的异常,throw用于抛出异常,catch用于捕获并处理由throw抛出的异常。 try-thow-catch构造了C++异常处理的基本结构,形式如下:

try{
	...
	if err1 throw xx1;
	...
	if err2 throw xx2;
	...
	if errn throw xxn;
}
catch(type1 arg){....}
catch(type2 arg){....}
catch(typen arg){....}

2.1 对传统错误处理的改造

#include <iostream>
#include <cstdio>
#include <csetjmp>
using namespace std;
class A{
	public:
		A(void){
			cout << "A(void)" << endl;
		}
		~A(){
			cout << "~A()" << endl;
		}
};
int func3(){
	A c;
	FILE *fp = fopen("./a.txt", "r");
******************************************************
	if(fp == NULL){
		throw -1;
	}
********************************************************
	cout << "open a.txt successed" << endl;
	fclose(fp);
	return 0;
}
int func2(){
	A b;
	func3();
	return 0;
}
int func1(void){
	A a;
	func2();
	return 0;
}
int main(void){
*************************************************************
	try{
		func1();
	}
	catch(int err){
		if(err == -1){
			cout << "handle file open failed" << endl;
			return -1;
		}
	}
*****************************************************************
	return 0;
}

2.2 异常处理流程

  • 未执行到throw时

在这里插入图片描述

  • 执行到throw时
    在这里插入图片描述
//定义错误类型的类对象
class FileErr{
private:
	string filename;
	int line;
public:
	FileErr(const string &name, int num){
		filename = name;
		line = num;
	}
	void print(void){
		cout << filename << ": "<< line << ":" << "file open failed" << endl;
	}
};
//检测
try{
	func1();
}
//抛出
if(fp == NULL){
	throw FileErr(__FILE__, __LINE__);
}
//捕获
catch(FileErr e){
	e.print();
	return -1;
}

注意:catch在进行数据异常类型匹配时,不会进行数据类型的默认转换,只有与异常类型精确匹配的catch块才会被执行。

3.函数的异常说明

当一个函数声明中不带任何异常描述时,它可以抛出任何异常。

C++允许限制函数能够抛出的异常类型,限制方法时在函数声明后面添加一个throw参数表,在其中指定函数可以抛出的异常类型。

int fun(int, char) throw(int, char);

函数fun被限定只允许抛出int和char类型的异常,当fun函数抛出其他类型的异常时,程序将被异常终止。

如果函数不允许抛出任何异常,只需要指定throw限制表为不包括任何类型的空表。

int fun(int, char) throw();
#include <iostream>
#include <cstdio>
#include <csetjmp>
using namespace std;
class FileError{};
class MemoryError{};
void func(void) throw(FileError, MemoryError){
	throw FileError();
	//throw MemoryError();
	//throw -1;
}
int main(void){
	try{
		func();
	}
	catch(FileError& ex){
		cout << "file error" << endl;
		return -1;
	}
	catch(MemoryError& ex){
		cout << "memory error" << endl;
		return -1;
	}
	catch(int errnum){
		cout << "int error" << endl;
	}
	return 0;
}

4.标准异常类

C++库中专门设计了exception类表示异常。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

#include <iostream>
#include <cstdio>
#include <csetjmp>
using namespace std;
class FileError:public exception{
	public:
		virtual const char *what() const throw(){
			cout << "handle file error" << endl;
			return "FileError";
		}
};
class MemoryError:public exception{
	public:
		virtual const char *what() const throw(){
			cout << "handle memory error" << endl;
			return "MemoryErrorError";
		}
};
void func(void) throw(FileError, MemoryError){
	//throw FileError();
	throw MemoryError();
	//throw -1;
}
int main(void){
	try{
		func();
	}
	catch(exception& ex){
		cout << ex.what()<< endl;
		return -1;
	}
	return 0;
}

ileError();
throw MemoryError();
//throw -1;
}
int main(void){
try{
func();
}
catch(exception& ex){
cout << ex.what()<< endl;
return -1;
}
return 0;
}


















































































































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值