异常在C++用于错误处理,C语言中一般使用返回值表示错误,C++对错误处理进行了扩展,统一使用异常机制来处理程序中发生的错误。
C++的异常处理包括两个部分 ----- 抛出异常和捕获异常,如果抛出的异常被捕获,处理完之后程序会继续运行,如果抛出的异常未被捕获,将导致程序终止。
throw是用于抛出异常的关键字,用法如下:
throw 异常(对象);
在函数声明中应该指定可能抛出的异常,应该在函数声明指定。
void show();//该函数可能抛出任何异常 void show()throw();//该函数不抛出任何异常 void show()throw(char,int);//该函数可能抛出char和int型异常
/*03-异常的抛出和捕获*/
#include
#include
#include
using namespace std;
class A {
public:
//不抛出任何异常
void show()throw()
{
cout << "show A" << endl;
}
};
//foo函数可能抛出int,double,const char *,A *类型的异常
void foo()throw(int, double, const char*)
{
srand(time(0));
int s = rand() % 4;//0 1 2 3 4
cout << "foo start!" << endl;
if (s == 0) {
cout << "正常运行!" << endl;
}
else if (s == 1) {
//抛出int型异常
throw 1;
}
else if (s == 2) {
//抛出double型异常
throw 3.14;
}
else if (s == 3) {
//排除const char *型异常
throw "起火了";
}
cout << "foo finished!" << endl;
}
int main()
{
foo();
cout << "after foo!" << endl;
//vs会报错,抛出后没有处理
cout << "app finished!" << endl;
return 0;
}
捕获异常使用try…catch关键字,用法如下:
try{ //可能抛出异常的代码 }catch(异常类型1 变量){//根据类型捕获异常 //处理异常类型1的代码 }catch(异常类型2 变量){//根据类型捕获异常 //处理异常类型2的代码 //throw 变量 ----- 继续向上一层抛出 }… //… //异常被捕获后,执行对应的异常处理代码,然后继续执行try…catch之后的代码 //异常未被捕获,仍然导致程序终止 //捕获异常后,如果当前无法处理,可以继续抛出
/*03-异常的抛出和捕获*/
#include
#include
#include
using namespace std;
class A {
public:
//不抛出任何异常
void show()throw()
{
cout << "show A" << endl;
}
};
//foo函数可能抛出int,double,const char *,A *类型的异常
void foo()throw(int, double, const char*, A*)
{
srand(time(0));
int s = rand() % 5;//0 1 2 3 4
cout << "foo start!" << endl;
if (s == 0) {
cout << "正常运行!" << endl;
}
else if (s == 1) {
//抛出int型异常
throw 1;
}
else if (s == 2) {
//抛出double型异常
throw 3.14;
}
else if (s == 3) {
//排除const char *型异常
throw "起火了";
}
else if (s == 4) {
//排除A *型异常
throw new A;
}
cout << "foo finished!" << endl;
}
int main()
{
try {
foo();
cout << "after foo!" << endl;
}
catch (int e) {//捕获int异常
cout << "捕获到了int型异常=" << e << endl;
}
catch (double e) {//捕获double异常
cout << "捕获到了double型异常=" << e << endl;
}
catch (const char* e) {//捕获const char *异常
cout << "捕获到了const char *型异常=" << e << endl;
cout << "无法处理,继续抛出" << endl;
throw e;
}
catch (A* e) {//捕获A *异常
cout << "捕获到了A *型异常" << endl;
e->show();
delete e;
}
cout << "app finished!" << endl;
return 0;
}
练习:
实现捕获A *类型的异常,同时调用该异常的show函数。
异常处理的原则是分层次捕获和处理,捕获到了本层的异常就直接处理返回 捕获到了不属于本层的异常就继续抛出
C++中预定义类一些异常,为C++预定义的类和函数(string cin cout new…)服务,在编程中可以直接使用。
预定义的异常类都是exception的子类/间接子类,当调用C++预定义类中的成员函数和预定义的全局函数时,可能抛出这些异常。
使用C++预定义异常需要包含头文件
#include
exception类中有一个虚函数 ----- what(),该函数返回异常原因的字符串
在C++项目开发中,详细设计时应该设计好异常的框架,通常的做法就是定义一个异常的基类,项目中所有的异常都是该类的子类/间接子类。
在函数语句中抛出
try{ //… }catch(…){ //… }… //根据不同的异常进行不同的处理
注意:如果代码可能抛出的异常中有多态性的父子关系,捕获异常时必须先捕获子类异常,再捕获父类异常。
1.为MyArray类添加一个at成员函数,该函数可能抛出out_of_range的异常;
int &at(size_t n) { }
构造函数可能抛出bad_alloc异常。
在使用该类的代码中捕获这些异常。
1.扩展自定义异常的代码(dms_exception)
添加 服务器无响应的异常子类/服务器资源不足异常子类 继承 服务器异常类 添加 客户端网络无连接的异常子类/客户端发送数据越界异常子类 继承 客户端异常类
/*dms_exception.h*/
#ifndef DMS_EXCEPTION_H
#define DMS_EXCEPTION_H
#include
using namespace std;
//异常的基类
class dms_exception {
public:
dms_exception(string msd = "dms exception")throw();
//声明what方法
virtual string what()throw();
private:
string description; //描述
};
//服务器异常子类
class dms_server_exception :public dms_exception {
public:
dms_server_exception(string msg = "server exception")throw();
};
//客户端异常子类
class dms_client_exception :public dms_exception {
public:
dms_client_exception(string msg = "client exception")throw();
};
#endif // DMS_EXCEPTION_H
/*dms_exception.cpp*/
#ifndef DMS_EXCEPTION_H
#define DMS_EXCEPTION_H
#include
using namespace std;
//异常的基类
class dms_exception {
public:
dms_exception(string msd = "dms exception")throw();
//声明what方法
virtual string what()throw();
private:
string description; //描述
};
//服务器异常子类
class dms_server_exception :public dms_exception {
public:
dms_server_exception(string msg = "server exception")throw();
};
//客户端异常子类
class dms_client_exception :public dms_exception {
public:
dms_client_exception(string msg = "client exception")throw();
};
#endif // DMS_EXCEPTION_H
/*main.cpp
*/
#include
#include
#include
#include "dms_exception.h"
using namespace std;
//dms系统发送数据接口 ------ 服务器异常 客户端异常 ...
void send_data()
{
srand(time(0));
int r = rand() % 4;
if (r == 0) {
cout << "发送成功" << endl;
}
else if (r == 1) {//服务器异常
throw dms_server_exception("dms服务器异常");
}
else if (r == 2) {//客户端异常
throw dms_client_exception("dms客户端异常");
}
else if (r == 3) {//其他异常
throw dms_exception("dms其他异常");
}
}
int main()
{
//执行可能抛出异常的代码
try {
send_data();
}
catch (dms_server_exception& e) {
cout << "服务器异常" << endl;
cout << e.what() << endl;
}
catch (dms_client_exception& e) {
cout << "客户端异常" << endl;
cout << e.what() << endl;
}
catch (dms_exception& e) {
cout << "其他异常" << endl;
cout << e.what() << endl;
}
return 0;
}