首页 > 代码库 > C++中的异常
C++中的异常
一,异常的推演
1.函数与异常
平时我们在函数中出现异常情况时通常通过return终止函数并返回一个值,然后在函数上层来获取值并判断是什么异常情况。因为函数是栈结构的,所以return的时候是通过栈结构逐步往上的,不能够跨函数直接抛出,不方便。所以C++推出了异常机制,通过异常机制我们可以轻松的捕获要出现的异常。
2.C++中异常的基本演示
# include<iostream>using namespace std;/* 定义求商函数,如果除数为0,抛出double类型异常 */double div(double d1, double d2){ if (d2 == 0) { throw d2; } return d1 / d2;}int main(){ /* try...catch语句来捕获异常 */ try { double result = div(1.02, 0.0); } catch (double e) { /* C++中的异常严格要求类型匹配,即抛出什么的异常就catch什么类型的异常 */ cout << e << "不能作除数" << endl; } catch (...) { cout << "未知异常" << endl; } return 0;}
3.C++中异常的总结
- 异常的捕捉严格匹配数据类型,不支持类型自动转换,throw的是int类型则catch的必须是int类型否则不会匹配。
- 一般我们在异常最后加入catch(...)这样能够捕获任意异常。
二,自定义异常类
1.异常类
按照面向对象的思维,我们的异常也应该是一个对象,所以在抛出异常的时候,我们通常自定义一个异常类,然后把异常信息放入异常类中,然后在捕捉到异常对象的时候,再调用对象的方法,打印出异常的信息。
2.异常类代码演示
# define _CRT_SECURE_NO_WARNINGS# include<iostream>using namespace std;/* 自定义异常类 */class MyException{private: char * content;public: /* 异常类构造函数 */ MyException(const char * content) { this->content = new char[strlen(content) + 1]; strcpy(this->content, content); cout << "异常类有参构造函数执行" << endl; } /* 异常类拷贝构造函数 */ MyException(const MyException& me) { this->content = new char[strlen(me.content) + 1]; strcpy(this->content, me.content); cout << "异常类拷贝构造函数执行" << endl; } /* 异常类析构函数 */ ~MyException() { if (this->content != NULL) { delete[] this->content; this->content = NULL; } cout << "异常类的析构函数执行" << endl; } /* 异常类抛出异常信息 */ void toString() { cout << this->content << endl; }};/* 定义测试异常的函数 */double divide(double d1, double d2){ if (d2 == 0) { throw MyException("除数不能为0"); //throw new MyException("除数不能为0"); } return d1 / d2;}int main(){ try { double result = divide(1, 0); cout << "result = " << result << endl; } catch (MyException e) { // catch的异常是元素类型,执行的是拷贝构造函数,存在两个异常对象,释放两个异常对象,不合理 e.toString(); } catch (MyException * e) { // catch的异常是指针类型,必须我们手动调用delete方法才能调用析构函数,不合理 e->toString(); delete e; } catch (MyException& e) { // catch的是引用类型,是原先抛出的对象,会自动执行析构函数,我们使用引用来接收抛出的异常对象 e.toString(); } catch (...) { cout << "未知异常" << endl; } return 0;}
3.自定义异常类总结
- 抛出异常对象通常用引用的方式来catch这个对象,如果是元素catch异常对象则会执行拷贝构造函数,创建两个重复异常对象并释放两次对象,所以说不合理。如果catch的是指针类型,不会自动调用该对象的析构函数必须我们手动delete,也不符合自动调用的逻辑,所以使用引用的方式来catch异常对象。
三,标准异常类
1.标准异常类
C++中提供了标准的异常类,需要# include<exception>,标准异常类为exception,该类有个what函数,可以打印异常对象的异常信息。该what函数是虚函数,我们需要继承exception类并重写该what函数,在捕捉异常的时候,我们用父类的引用来接收自定义的标准异常类的子类对象(类型兼容性原则),然后打印该异常信息即可。
2.标准异常类演示
# include<iostream># include<exception>using namespace std;/* 继承自标准异常类 */class DivException :public exception{private: const char * ptr;public: /* 构造函数接收异常信息 */ DivException(const char * ptr) { this->ptr = ptr; } /* 重写what函数 */ virtual char const * what() const { cout << this->ptr << endl; return ptr; }};/* 测试异常函数 */int divi(int a, int b){ if (b == 0) { throw DivException("除数不能为0"); } return a / b;}int main(){ try { divi(10, 0); } catch (exception& e) { /* 使用exception引用接收自定义的子类对象 */ e.what(); } catch (...) { cout << "未知异常" << endl; } return 0;}
C++中的异常
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。