• exception错误处理库学习


    exception是c++标准库组件抛出的各种异常的基类,在c++开发的过程中我们经常会遇到各种各样的异常比如,打开文件失败,数组越界,等等,如果不想让程序崩溃,那么就需要使用一个异常类来处理这些异常错误,使得程序继续运行。下面我们来学习exception的基本使用。

    1.异常的使用示例

    我们先来看一个不使用exception的程序

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. class Polymorphic
    6. {
    7. virtual void member() {}
    8. };
    9. int main()
    10. {
    11. Polymorphic *pb = nullptr;
    12. typeid(*pb);
    13. cout << "Hello World!" << endl;
    14. return 0;
    15. }

    运行

     程序运行就崩溃了,然后我们再使用异常处理

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. class Polymorphic
    6. {
    7. virtual void member() {}
    8. };
    9. int main()
    10. {
    11. try {
    12. Polymorphic *pb = nullptr;
    13. typeid(*pb);
    14. } catch (std::exception &e) {
    15. std::cerr << "exception caught: " << e.what() << endl;
    16. }
    17. cout << "Hello World!" << endl;
    18. return 0;
    19. }

    运行结果:

    程序抛出空指针的异常,但程序不会崩溃,因此使用exception时程序出现错误时,可以抛出来,避免程序崩溃,程序员需要处理抛出的异常。

    2.current_exception捕获当前异常到exception_ptr中
    1. #include
    2. #include
    3. using namespace std;
    4. //1.current_exception捕获当前异常到exception_ptr中
    5. void handle_exception(std::exception_ptr eptr) //按值传递
    6. {
    7. try {
    8. if(eptr)
    9. std::rethrow_exception(eptr);
    10. } catch (const std::exception &e) {
    11. std::cout << "Caught exception=====" << e.what() << endl;
    12. }
    13. }
    14. int main()
    15. {
    16. std::exception_ptr eptr;
    17. try {
    18. std::string().at(1);//知成一个std::out_of_range
    19. } catch (...) {
    20. //捕获当前异常
    21. eptr = std::current_exception();
    22. }
    23. handle_exception(eptr);
    24. cout << "Hello World!" << endl;
    25. return 0;
    26. }

    运行结果:

     3.make_exception_ptr 创建一个异常对象

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. int main()
    6. {
    7. auto p = std::make_exception_ptr(std::logic_error("logic_error"));
    8. try {
    9. std::rethrow_exception(p);
    10. } catch (const std::exception& e) {
    11. std::cout << "exception caught:" << e.what() << endl;
    12. }
    13. cout << "Hello World!" << endl;
    14. return 0;
    15. }

    运行结果:

    4.rethrow_exception 从一个 std::exception_ptr 抛出异常

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. int main()
    7. {
    8. std::exception_ptr p;
    9. try {
    10. std::vector<int> myvector(10);
    11. myvector.at(20) = 100; //vector::at throws on out-of-range
    12. } catch (const std::exception& e) { //捕获异常
    13. cout << "e.what ======== " << e.what() << endl;
    14. p = current_exception();
    15. cout << "exception caught, but continuing... typeid(p).name ====" << typeid(p).name() << endl;
    16. }
    17. cout << "(after exception)" << endl;
    18. try {
    19. std::rethrow_exception(p);
    20. } catch (const std::exception& e) {
    21. std::cout << "exception caught: " << e.what() << endl;
    22. }
    23. cout << "Hello World!" << endl;
    24. return 0;
    25. }

    运行结果:

    5.terminate 异常终止

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. int main()
    7. {
    8. char *p;
    9. cout << "Attempting to allocate 2GB..." << endl;
    10. try {
    11. p = new char[2147483647]; //2147483648====>2GB
    12. } catch (const exception &e) {
    13. cout << "excepter=======e.what()======= " << e.what() << endl;
    14. cout << "Error: could not allocate storage." << endl;
    15. terminate();
    16. }
    17. delete[] p;
    18. cout << "Hello World!" << endl;
    19. return 0;
    20. }

     运行结果:

    6.设置终止异常函数

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. void myterminate()
    7. {
    8. std::cerr << "terminate handler called" << endl;
    9. abort(); //forces abnormal termination
    10. }
    11. int main()
    12. {
    13. std::set_terminate(myterminate);
    14. throw 0; //unhandled exception: calls terminate handler
    15. cout << "Hello World!" << endl;
    16. return 0;
    17. }

    运行结果:

    7.throw_width_nested嵌套异常

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. using namespace std;
    8. void openFile(const std::string &fileName)
    9. {
    10. try {
    11. std::ifstream file(fileName);
    12. file.exceptions(std::ios_base::failbit);
    13. } catch (...) {
    14. std::cout << "openFile=====fileName===" << fileName << endl;
    15. std::throw_with_nested(std::runtime_error("Couldn't open " + fileName));
    16. }
    17. }
    18. //捕捉异常并将其包装于nested_exception
    19. void throwWithNested()
    20. {
    21. try {
    22. openFile("nonexistent.txt");
    23. } catch (const exception &e) {
    24. cout << "throwWithNested()====e.what===" << e.what() << endl;
    25. }
    26. }
    27. int main()
    28. {
    29. try {
    30. throwWithNested();
    31. } catch (const std::exception &e) {
    32. cout << "exception =====e.what====== " << e.what() << endl;
    33. }
    34. cout << "Hello World!" << endl;
    35. return 0;
    36. }

    运行结果:

     

    8.rethrow_if_nested如果是嵌套抛出异常

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. using namespace std;
    8. // 打印异常的解释性字符串。若异常内嵌,则递归打印其保有的异常的解释
    9. void printException(const std::exception &e, int level = 0)
    10. {
    11. cout << std::string(level, ' ') << "exception: " << e.what() << endl;
    12. try {
    13. std::rethrow_if_nested(e);
    14. } catch (const std::exception &e) {
    15. printException(e, level + 1);
    16. }catch(...) {
    17. cout << "printException=======e.what== " << e.what() << " level = " << level << endl;
    18. }
    19. }
    20. void openFile(const std::string &fileName)
    21. {
    22. try {
    23. std::ifstream file(fileName);
    24. file.exceptions(std::ios_base::failbit);
    25. } catch (...) {
    26. std::cout << "openFile=====fileName===" << fileName << endl;
    27. std::throw_with_nested(std::runtime_error("Couldn't open " + fileName));
    28. }
    29. }
    30. //捕捉异常并将其包装于nested_exception
    31. void throwWithNested()
    32. {
    33. try {
    34. openFile("nonexistent.txt");
    35. } catch (const exception &e) {
    36. cout << "throwWithNested()====e.what===" << e.what() << endl;
    37. std::throw_with_nested(e);
    38. }
    39. }
    40. int main()
    41. {
    42. try {
    43. throwWithNested();
    44. } catch (const std::exception &e) {
    45. printException(e);
    46. }
    47. cout << "Hello World!" << endl;
    48. return 0;
    49. }

    运行结果:

     

    参考:

    - C++ Reference

    标准库头文件 - cppreference.com

  • 相关阅读:
    JSP如何使用request获取当前访问者的真实IP呢?
    触控笔有必要买吗?便宜好用的手写笔推荐
    如何验证高压放大器的性能好坏呢
    Tensorflow笔记——卷积神经网络
    Ubuntu镜像下载地址
    【Lua】脚本入门
    软件测试 - Linux的远程连接
    [附源码]Python计算机毕业设计大学生心理健康管理系统
    【机器学习】sklearn对数据预处理
    K8s 环境下. DataGrip连接 kerberos认证的hive
  • 原文地址:https://blog.csdn.net/chenyijun/article/details/125822678