当前位置: 首页 > news >正文

exception错误处理库学习

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

1.异常的使用示例

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

#include <iostream>
#include <typeinfo>
#include <exception>

using namespace std;

class Polymorphic
{
    virtual void member() {}
};


int main()
{

    Polymorphic *pb = nullptr;
    typeid(*pb);

    cout << "Hello World!" << endl;
    return 0;
}

运行

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

#include <iostream>
#include <typeinfo>
#include <exception>

using namespace std;

class Polymorphic
{
    virtual void member() {}
};


int main()
{

    try {
        Polymorphic *pb = nullptr;
        typeid(*pb);
    } catch (std::exception &e) {
        std::cerr << "exception caught: " << e.what() << endl;
    }
    cout << "Hello World!" << endl;
    return 0;
}

运行结果:

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

2.current_exception捕获当前异常到exception_ptr中
#include <iostream>
#include <exception>

using namespace std;


//1.current_exception捕获当前异常到exception_ptr中
void handle_exception(std::exception_ptr eptr) //按值传递
{
    try {
        if(eptr)
            std::rethrow_exception(eptr);
    } catch (const std::exception &e) {
        std::cout << "Caught exception=====" << e.what() << endl;
    }
}

int main()
{
    std::exception_ptr eptr;
    try {
        std::string().at(1);//知成一个std::out_of_range
    } catch (...) {
        //捕获当前异常
        eptr = std::current_exception();
    }

    handle_exception(eptr);
    cout << "Hello World!" << endl;
    return 0;
}

运行结果:

 3.make_exception_ptr 创建一个异常对象

#include <iostream>
#include <typeinfo>
#include <exception>

using namespace std;


int main()
{
    auto p = std::make_exception_ptr(std::logic_error("logic_error"));
    try {
        std::rethrow_exception(p);
    } catch (const std::exception& e) {
        std::cout << "exception caught:" << e.what() << endl;
    }
    cout << "Hello World!" << endl;
    return 0;
}

运行结果:

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

#include <iostream>
#include <typeinfo>
#include <exception>
#include <vector>

using namespace std;


int main()
{
    std::exception_ptr p;
    try {
        std::vector<int> myvector(10);
        myvector.at(20) = 100; //vector::at throws on out-of-range
    } catch (const std::exception& e) { //捕获异常
        cout << "e.what ======== " << e.what() << endl;
        p = current_exception();
        cout << "exception caught, but continuing...  typeid(p).name ====" << typeid(p).name() << endl;
    }
    cout << "(after exception)" << endl;
    try {
        std::rethrow_exception(p);
    } catch (const std::exception& e) {
        std::cout << "exception caught: " << e.what() << endl;
    }
    cout << "Hello World!" << endl;

    return 0;
}

运行结果:

5.terminate 异常终止

#include <iostream>
#include <typeinfo>
#include <exception>
#include <vector>

using namespace std;

int main()
{
    char *p;
    cout << "Attempting to allocate 2GB..." << endl;
    try {
        p = new char[2147483647]; //2147483648====>2GB
    } catch (const exception &e) {
        cout << "excepter=======e.what()======= " << e.what() << endl;
        cout << "Error: could not allocate storage." << endl;
        terminate();
    }
    delete[] p;
    cout << "Hello World!" << endl;
    return 0;
}

 运行结果:

6.设置终止异常函数

#include <iostream>
#include <typeinfo>
#include <exception>
#include <vector>

using namespace std;


void myterminate()
{
    std::cerr << "terminate handler called" << endl;
    abort(); //forces abnormal termination
}

int main()
{
    std::set_terminate(myterminate);
    throw 0; //unhandled exception: calls terminate handler
    cout << "Hello World!" << endl;
    return 0;
}

运行结果:

7.throw_width_nested嵌套异常

#include <iostream>
#include <typeinfo>
#include <exception>
#include <vector>
#include <fstream>
#include <string>

using namespace std;


void openFile(const std::string &fileName)
{
    try {
        std::ifstream file(fileName);
        file.exceptions(std::ios_base::failbit);
    } catch (...) {
        std::cout << "openFile=====fileName===" << fileName << endl;
        std::throw_with_nested(std::runtime_error("Couldn't open " + fileName));
    }
}

//捕捉异常并将其包装于nested_exception
void throwWithNested()
{
    try {
        openFile("nonexistent.txt");
    } catch (const exception &e) {
        cout << "throwWithNested()====e.what===" << e.what() << endl;
    }
}

int main()
{
    try {
        throwWithNested();
    } catch (const std::exception &e) {
        cout << "exception =====e.what====== " << e.what() << endl;
    }
    cout << "Hello World!" << endl;
    return 0;
}

运行结果:

 

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

#include <iostream>
#include <typeinfo>
#include <exception>
#include <vector>
#include <fstream>
#include <string>

using namespace std;


// 打印异常的解释性字符串。若异常内嵌,则递归打印其保有的异常的解释
void printException(const std::exception &e, int level = 0)
{
    cout << std::string(level, ' ') << "exception: " << e.what() << endl;
    try {
        std::rethrow_if_nested(e);
    } catch (const std::exception &e) {
        printException(e, level + 1);
    }catch(...) {
        cout << "printException=======e.what== " << e.what() << " level = " << level << endl;
    }
}


void openFile(const std::string &fileName)
{
    try {
        std::ifstream file(fileName);
        file.exceptions(std::ios_base::failbit);
    } catch (...) {
        std::cout << "openFile=====fileName===" << fileName << endl;
        std::throw_with_nested(std::runtime_error("Couldn't open " + fileName));
    }
}

//捕捉异常并将其包装于nested_exception
void throwWithNested()
{
    try {
        openFile("nonexistent.txt");
    } catch (const exception &e) {
        cout << "throwWithNested()====e.what===" << e.what() << endl;
        std::throw_with_nested(e);
    }
}

int main()
{
    
    try {
        throwWithNested();
    } catch (const std::exception &e) {
        printException(e);
    }
    cout << "Hello World!" << endl;
    return 0;
}

运行结果:

 

参考:

<exception> - C++ Reference

标准库头文件 <exception> - cppreference.com

相关文章:

  • 蔚来、小鹏、吉利走到了跨界分叉口
  • 神卓互联SDWAN技术实现异地组网办公(无需硬件)
  • Redis分布式锁(下篇)
  • Vue--整合SVG Icon图标--方法/实例
  • STC15单片机-整合代码,完成软件设计
  • 直流有刷电机调速原理及Matlab/Simulink仿真
  • 基于bootstrap+Java+MySQL的高校成绩管理系统
  • java基于ssm+vue+elementui的旅游线路分享管理系统
  • 最近公共祖先 LCA
  • Deterministic Policy Gradient Algorithms
  • Java8时间日期库DateTime API及示例
  • np.random.seed(), torch.manual_seed(args.seed)
  • 真真正正的九面阿里才定级 P6+ 支持背调,还不来看?(建议收藏)
  • Fedora 24 Beta 版发布下载!
  • k-NN分类算法详解与分析(k近邻分类算法)
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • DataBase in Android
  • Fastjson的基本使用方法大全
  • Git的一些常用操作
  • HashMap ConcurrentHashMap
  • Java程序员幽默爆笑锦集
  • JS数组方法汇总
  • Python学习笔记 字符串拼接
  • 对超线程几个不同角度的解释
  • 关于 Cirru Editor 存储格式
  • 技术:超级实用的电脑小技巧
  • 普通函数和构造函数的区别
  • 如何在GitHub上创建个人博客
  • 删除表内多余的重复数据
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 算法之不定期更新(一)(2018-04-12)
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​决定德拉瓦州地区版图的关键历史事件
  • ​批处理文件中的errorlevel用法
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • #pragma pack(1)
  • (2)Java 简介
  • (2015)JS ES6 必知的十个 特性
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (接口封装)
  • (四)汇编语言——简单程序
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • .net 验证控件和javaScript的冲突问题
  • .NET的微型Web框架 Nancy
  • .NET与 java通用的3DES加密解密方法
  • [C++]Leetcode17电话号码的字母组合
  • [C++]运行时,如何确保一个对象是只读的
  • [CF]Codeforces Round #551 (Div. 2)
  • [Flex] PopUpButton系列 —— 控制弹出菜单的透明度、可用、可选择状态
  • [GN] Vue3快速上手1
  • [HarmonyOS]第一课:从简单的页面开始
  • [HDU3710]Battle over Cities