异常处理的实现:
1.异常处理的语法:
throw表达式
当程序发现不能处理的异常时 ,可以使用throw表达式抛掷这个异常,如果有多种要抛掷的异常应该用不同的 *** 作数来区别
try块语法:
try
复合语句
catch(异常声明)
复合语句
catch(异常声明)
复合语句
...
处理过程:
注意事项:
当抛出的异常与catch匹配时
- catch子句中声明的异常类型就是抛出异常对象的类型或引用
- catch子句中声明的异常类型是抛出异常对象的类型的公共基类或其引用
- 当抛出异常类型和catch中的声名的一仓管类型都是指针类型时,前者到后者可以隐含转换
#include
#include
using namespace std;
//处理0异常
int text(int a, int b)
{
if (b == 0)
//当分母为0时抛出异常
throw a;
return a / b;
}
int main()
{
//try块
try {
cout << "3/6=" << text(3, 6) << endl;
cout << "2/0=" << text(2, 0) << endl;
cout << "4/5=" << text(4, 5) << endl;
}
//异常声明类型要与 抛出异常的类型相同
catch (int a) {
cout << "分母不能为0" << endl;
}
//当处理了异常之后后面的语句都不会处理
cout << "结束" << endl;
return 0;
}
catch(...) | 可以捕获全部异常 |
函数抛出异常
void fun() throw(a,b,c,d) | 可以抛出4种类型的异常 |
void fun() | 可以抛出所有类型的异常 |
void fun()throw() | 不抛出任何异常 |
当一个函数抛出了不允许抛出的异常时,unexpected函数会调用
该函数默认是调用 terminate 函数中止程序 ,用户可以自定义自己的unexpected函数
异常处理中的构造和析构:异常抛出前会自动调用析构函数
异常被抛出后,进入try块,到异常被抛出前,这期间在栈上构造(未被析构的)的所有对象都会被自动析构,这一过程称为“解旋”
#include
#include
using namespace std;
class person
{
public:
//初始化
person(const string &message):message(message){}
~person(){}
const string &getMessage()const { return message; }
private:
string message;
};
class son
{
public:
//构造
son() { cout << "1111111111111111" << endl; }
//析构
~son() { cout << "222222222222222" << endl; }
};
void func()throw(person)
{
//创建一个son对象
//调用构造函数
son s;
cout << "throw person in func()" << endl;
//调用析构函数
//抛出异常
throw person("3333333");
}
int main()
{
cout << "in main function" << endl;
try {
func();
}
catch (person& p)
{
cout << "caught an exception:" << p.getMessage() << endl;
}
cout << "resume the execution of main()" << endl;
return 0;
return 0;
}
运行结果
c++标准程序库异常处理:基类:Exception 提供一个成员函数:what()
virtaul const char*what()const throw();
常用的一些异常类:
异常类 | 头文件 | 含义 |
bad_alloc | exception | new 动态分配空间失败 |
bad_case | new | 执行dynamic_cast失败 |
bad_typeid | typeinfo | 对某个空指针p执行统一佩戴(*p) |
bad_exception | typeinfo | 在fun()中抛出了不允许的异常调用了unexpected若unexpected又一次抛出异常了fun()的异常声明不允许的异常且fun()的异常声明表中有bed_exception则会有一个bed_exception异常在fun()的调用点被抛出 |
ios_base::failure | ios | 用来表示c++的输入输出流执行时的错误 |
underflow_error | stdexcept | 算术运算向下溢出 |
overflow_error | stdexcept | 算术运算向上溢出 |
range_error | stdexcept | 内部计算时发生作用域的错误 |
out_of_range | stdexcept | 表示一个参数值不在允许的范围之内 |
length_error | stdexcept | 尝试创建一个长度超过最大允许值的对象 |
invalid_argument | stdexcept | 尝试向函数传入无效参数 |
domain_error | stdexcept | 执行一段程序的先决条件不满足 |
#include
#include
using namespace std;
#include
//头文件
#include
//给出三角形 三边返回面积
//异常类 invalid_argument
double area(double a, double b, double c)throw(invalid_argument)
{
//边长都要为正数
if (a <=0 || b <=0 || c <= 0)
{
throw invalid_argument("要为正数");
}
//两边之和大于第三边
if (a + b <= c || a + c <= b || b + c <= a)
{
throw invalid_argument("两边之和要大于第三边");
}
double s= (a + b + c) / 2;
return sqrt(s*(s - a)*(s - b)*(s - c));
}
int main()
{
double a, b, c;
cout << "请输入三个边长" << endl;
cin >> a >> b >> c;
try {
double s = area(a, b, c);
cout << "面积为:" << s;
}
//因为标准类都是eception的派生 所以直接创建exception类型
catch (exception&e)
{
cout << "Error:" << e.what() << endl;
}
return 0;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)