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

嵌入式学习-C嘎嘎-Day06

嵌入式学习-C嘎嘎-Day06

1. 什么是异常?

2. 抛出异常

3. 捕获异常

4. 标准异常族

5. 异常捕获技巧

5.1 捕获基类异常

5.2 多重捕获

1. 什么是异常?

异常是程序在运行期间产生的问题,即没有语法错误,出现的是逻辑错误,C++提供了一种转移程序控制权的方式:

  • 异常经过程序员正确处理,继续运行;
  • 异常没有经过程序员正确处理,运行终止。

例如之前使用string的at函数,范围越界的问题等。

处理异常的方式有两种:

  • 抛出异常 throw
  • 捕获异常 try-catch

2. 抛出异常

使用throw关键字可以抛出一个异常对象,throw可以抛出任何类型的异常对象,抛出到当前代码调用的上一级。

#include <iostream>

using namespace std;

double divide(double a,double b)
{
    if(b == 0)
        throw "除数不能为0!!!";
    return a/b;
}

int main()
{
    cout << divide(3,2) << endl; // 1.5
    cout << divide(2,0) << endl; // 终止运行

    cout << "程序运行结束" << endl;
    return 0;
}

3. 捕获异常

捕获异常分为try代码块和catch代码块,try块中放置可能抛出异常的代码,catch块放置异常类型匹配的代码,处理逻辑如下:

情况1:抛出异常并捕获成功

#include <iostream>

using namespace std;

double divide(double a,double b)
{
    if(b == 0)
        throw "除数不能为0!!!";
    return a/b;
}

int main()
{
    try
    {
        cout << divide(2,0) << endl;
        cout << "A" << endl;
    }catch(const char* e)
    {
        cout << e << endl;
        // 正常开发下,需要修复逻辑错误
    }
    cout << "程序运行结束" << endl;
    return 0;
}

情况2:抛出异常,捕获失败

#include <iostream>

using namespace std;

double divide(double a,double b)
{
    if(b == 0)
        throw "除数不能为0!!!";
    return a/b;
}

int main()
{
    try
    {
        cout << divide(2,0) << endl;
        cout << "A" << endl;
    }catch(int e)
    {
        cout << e << endl;
        // 正常开发下,需要修复逻辑错误
    }
    cout << "程序运行结束" << endl;
    return 0;
}

情况3:没有抛出异常,正常直接try块结束。

#include <iostream>

using namespace std;

double divide(double a,double b)
{
    if(b == 0)
        throw "除数不能为0!!!";
    return a/b;
}

int main()
{
    try
    {
        cout << divide(2,1) << endl;
        cout << "A" << endl;
    }catch(int e)
    {
        cout << e << endl;
        // 正常开发下,需要修复逻辑错误
    }
    cout << "程序运行结束" << endl;
    return 0;
}

异常如果不在当前层次进行处理,也可以交给上一级进行处理,但是如果主函数中还没有正确处理,则程序终止。

#include <iostream>

using namespace std;

double divide(double a,double b)
{
    if(b == 0)
        throw "除数不能为0!!!";
    return a/b;
}

void test()
{
    try
    {
        cout << divide(2,0) << endl;
        cout << "A" << endl;
    }catch(int e)
    {
        cout << "B" << endl;
        cout << e << endl;
        // 正常开发下,需要修复逻辑错误
    }
}

int main()
{
    try
    {
        test();
    }catch(const char* e)
    {
        cout << "C" << endl;
        cout << e << endl;
        // 正常开发下,需要修复逻辑错误
    }
    cout << "程序运行结束" << endl;
    return 0;
}

4. 标准异常族

C++为常见的异常类型进行层次划分,通过继承实现。

使用标准异常族需要引入头文件 #include <stdexcept>

自定义异常类型应该通过继承加入上面的结构。

#include <iostream>
#include <stdexcept> // 头文件

using namespace std;

class ZeroException:public exception
{
public:
    // throw() 是异常规格说明,表示what函数不会抛出任何异常
    const char* what() const throw()
    {
        return "除数不能为0!!!";
    }
};

double divide(double a,double b)
{
    if(b == 0)
        throw ZeroException();
    return a/b;
}

int main()
{
    try
    {
        cout << divide(2,0) << endl;
        cout << "A" << endl;
    }catch(const ZeroException& e)
    {
        cout << e.what() << endl;
        // 正常开发下,需要修复逻辑错误
    }
    cout << "程序运行结束" << endl;
    return 0;
}

5. 异常捕获技巧

5.1 捕获基类异常

所有抛出的派生类异常对象都可以被其基类异常类型捕获。

#include <iostream>
#include <stdexcept> // 头文件

using namespace std;

void poly_except()
{
    int a = 1;
    if(a == 1)
    {
        throw out_of_range("hah");
    }else {
        throw domain_error("随便");
    }
}

int main()
{
    try
    {
        poly_except();
    }catch(const logic_error& e)
    {
        cout << e.what() << endl;
        // TODO 修复逻辑代码
    }

    cout << "程序运行结束" << endl;
    return 0;
}

5.2 多重捕获

可以使用多个catch块配合try块进行异常捕获,catch的顺序要求派生类异常先捕获,基类异常后捕获

#include <iostream>
#include <stdexcept> // 头文件

using namespace std;

void poly_except()
{
    int a = 2;
    if(a == 1)
    {
        string s;
        s.at(-1);
    }else {
        throw underflow_error("f");
    }
}

int main()
{
    try
    {
        poly_except();
    }catch(const out_of_range& e)
    {
        cout << "A" << endl;
    }catch(const domain_error& e)
    {
        cout << "B" << endl;
    }catch(const logic_error& e)
    {
        cout << "C" << endl;
    }catch(const exception& e)
    {
        cout << "D" << endl;
    }

    cout << "程序运行结束" << endl;
    return 0;
}

还可以单独使用一个...捕获所有异常,但是不推荐。

#include <iostream>
#include <stdexcept> // 头文件

using namespace std;

void poly_except()
{
    int a = 2;
    if(a == 1)
    {
        string s;
        s.at(-1);
    }else {
        throw "fdfdfd";
    }
}

int main()
{
    try
    {
        poly_except();
    }catch(...)
    {
        cout << "A" << endl;
    }
    cout << "程序运行结束" << endl;
    return 0;
}

C++的异常处理机制并不完善,是否使用取决于开发团队的要求。


http://www.kler.cn/a/402698.html

相关文章:

  • 2024最新python使用yt-dlp
  • 使用timm库加载模型与模型权重
  • std::unique_ptr源码中构造函数的偏特化。_Unique_ptr_enable_default_t
  • element-plus教程:Input Number 数字输入框
  • 使用 Elastic 收集 Windows 遥测数据:ETW Filebeat 输入简介
  • HTB:Buff[WriteUP]
  • 11.20Pytorch_概数和基础
  • 深度学习:神经网络中的非线性激活的使用
  • 深入理解C++11右值引用与移动语义:高效编程的基石
  • Android开发实战班 - 现代 UI 开发之自定义 Compose 组件
  • Java基于微信小程序的校园跑腿平台(V2.0)
  • elementUI 表格组件结合单选框做单选效果显示
  • 人形机器人开发、XR仿真训练、影视动画制作,一副手套支持多种应用
  • 安装CLIP
  • 前端项目支持tailwindcss写样式
  • 【Linux】编译器gcc/g++、动静态库
  • docker pull命令拉取镜像失败的解决方案
  • 机器学习笔记——聚类算法(Kmeans、GMM-使用EM优化)
  • ansible从入门到精通(完整篇)
  • 软件测试 —— 自动化基础
  • opencv项目:自动评分答题卡识别系统
  • layui合并table相同内的行
  • web——sqliabs靶场——第十三关——报错注入+布尔盲注
  • 告别反馈滞后!看板管理让UX设计流程更流畅
  • 208.实现前缀树 207.课程表
  • 22.UE5控件切换器,存档列表,