经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
C++ 异常机制(下)
来源:cnblogs  作者:东南亚季风  时间:2021/1/18 16:38:03  对本文有异议

八、C++标准异常类

C++标准库异常类继承层次中的根类为exception,其定义在exception头文件中,它是C++标准库所有函数抛出异常的基类,exception的接口定义如下:

  1. namespace std {
  2. class exception {
  3. public:
  4. exception() throw(); //不抛出任何异常
  5. exception(const exception& e) throw();
  6. exception& operator= (const exception& e) throw();
  7. virtual ~exception() throw)();
  8. virtual const char* what() const throw(); //返回异常的描述信息
  9. };
  10. }

先来看一下 exception 类的直接派生类:

异常名称 说 明
logic_error 逻辑错误。
runtime_error 运行时错误。
bad_alloc 使用 new 或 new[ ] 分配内存失败时抛出的异常。
bad_typeid 使用 typeid 操作一个 NULL 指针,而且该指针是带有虚函数的类,这时抛出 bad_typeid 异常。
bad_cast 使用 dynamic_cast 转换失败时抛出的异常。
ios_base::failure io 过程中出现的异常。
bad_exception 这是个特殊的异常,如果函数的异常列表里声明了 bad_exception 异常,当函数内部抛出了异常列表中没有的异常时,如果调用的 unexpected() 函数中抛出了异常,不论什么类型,都会被替换为 bad_exception 类型。

logic_error 的派生类:

异常名称 说 明
length_error 试图生成一个超出该类型最大长度的对象时抛出该异常,例如 vector 的 resize 操作。
domain_error 参数的值域错误,主要用在数学函数中,例如使用一个负值调用只能操作非负数的函数。
out_of_range 超出有效范围。
invalid_argument 参数不合适。在标准库中,当利用string对象构造 bitset 时,而 string 中的字符不是 0 或1 的时候,抛出该异常。

runtime_error 的派生类:

异常名称 说 明
range_error 计算结果超出了有意义的值域范围。
overflow_error 算术计算上溢。
underflow_error 算术计算下溢。

九、编写自己的异常类

原则:建议继承标准异常类,并重载父类的what函数和析构函数

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <iostream>
  3. #include<stdexcept>
  4. using namespace std;
  5. class Person {
  6. public:
  7. Person() {
  8. mAge = 0;
  9. }
  10. void setAge(int age) {
  11. if (age < 0 || age > 100) {
  12. throw out_of_range("年龄应该在0-100之间!");
  13. }
  14. this->mAge = age;
  15. }
  16. public:
  17. int mAge;
  18. };
  19. //test01()使用标准库的异常类,下面的exception可以换为out_of_range
  20. void test01() {
  21. Person p;
  22. try {
  23. p.setAge(1000);
  24. }
  25. catch (exception e) {
  26. cout << e.what() << endl;
  27. }
  28. }
  29. //自己写个异常类,重载父类的what函数和析构函数
  30. class MyOutOfRange : public exception {
  31. public:
  32. MyOutOfRange(const char* error) {
  33. pError = new char[strlen(error) + 1];
  34. strcpy(pError, error);
  35. }
  36. ~MyOutOfRange() {
  37. if (pError != NULL) {
  38. delete[] pError;
  39. }
  40. }
  41. virtual const char* what() const {
  42. return pError;
  43. };
  44. public:
  45. char* pError;
  46. };
  47. void fun02() {
  48. throw MyOutOfRange("我自己的out_of_range!");
  49. }
  50. void test02() {
  51. try {
  52. fun02();
  53. }
  54. catch (exception& e) {
  55. cout << e.what() << endl;
  56. }
  57. }
  58. int main(void)
  59. {
  60. test01();//结果:年龄应该在0-100之间!
  61. //test02();//结果:我自己的out_of_range!
  62. return 0;
  63. }

十、继承在异常中的应用

异常尽量抛个类对象(基类),不要再用 -1 或 char* 。

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <iostream>
  3. using namespace std;
  4. //异常基类
  5. class BaseMyException {
  6. public:
  7. virtual void what() = 0;
  8. virtual ~BaseMyException() {}
  9. };
  10. class TargetSpaceNullException : public BaseMyException {
  11. public:
  12. virtual void what() {
  13. cout << "目标空间空!" << endl;
  14. }
  15. ~TargetSpaceNullException() {}
  16. };
  17. class SourceSpaceNullException : public BaseMyException {
  18. public:
  19. virtual void what() {
  20. cout << "源空间为空!" << endl;
  21. }
  22. ~SourceSpaceNullException() {}
  23. };
  24. void copy_str(char* taget, char* source) {
  25. if (taget == NULL) {
  26. throw TargetSpaceNullException();
  27. }
  28. if (source == NULL) {
  29. throw SourceSpaceNullException();
  30. }
  31. //int len = strlen(source) + 1;
  32. while (*source != '\0') {
  33. *taget = *source;
  34. taget++;
  35. source++;
  36. }
  37. }
  38. int main(void) {
  39. const char* source = "abcdefg";
  40. char buf[1024] = { 0 };
  41. try {
  42. copy_str(buf, NULL);
  43. }
  44. catch (BaseMyException& ex) {
  45. ex.what();
  46. }
  47. cout << buf << endl;
  48. return 0;
  49. }
  50. //结果:源空间为空!

原文链接:http://www.cnblogs.com/gqw-myblogs/p/14286832.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号