C++之异常

1.异常的概念及其使用

    1.1 异常的概念

异常是一种用于处理错误的机制,它允许程序在检查到错误条件时,能够从一个代码块转到另一个代码块,以处理改错误,而不是直接崩溃返回不确定的结果。

       C++的异常处理机制依赖于三个关键字:try(),throw(抛出),catch(捕获)

   1.2 异常的抛出和捕获

   1.程序出现问题的时候我们会抛出一个对象来引发一个异常,该对象的类型以及当前的调用链决定了应该由哪个catch的处理代码来处理该异常

   2.被选中的处理代码是调用链中与该对象类型匹配,并且离抛出异常位置最近的那一个,根据抛出对象的类型和内容,程序抛出异常的那部分会告知异常处理部分到底发生了什么错误。

   3.当throw执行后,throw后面的语句将不再执行,程序从throw执行的位置跳到与之匹配的catch位置,catch可能是同一个函数局部的catch,也可能是调用链中另一个函数的catch,控制权从throw位置转移到了catch位置。

这里有两种重要的含义:

(1)沿着调用链的函数会提前退出。

(调用链就是多重函数的调用,例如函数1调用函数2,函数2调用函数3,提前退出的意思是如果函数3发生异常抛出后,函数3没有catch,但函数2有,就交给函数2catch)

(2)一旦程序开始执行异常处理程序,沿着调用链创建的函数都会销毁。

   4.抛出异常对象后,会生成一个异常对象的拷贝(因为抛出的异常对象可能是一个局部对象,根据上面可知,这样就可以把函数3的异常传给函数2,从而达到让函数2catch的作用)

     1.3 栈展开

1.抛出异常后,程序暂停当前函数的执行,开始寻找与之匹配的catch子句,首先检查throw本身是否在try块内部,如果在则查找匹配的catch语句,如果在则查找匹配的catch语句,如果有匹配的,则跳到catch的地方进行处理。

2.如果当前函数没有try/catch子句,或有try/catch子句但类型不匹配,则退出当前函数,继续在函数的调用链寻找catch的过程称为栈展开。

3.如果到达main函数,依旧没有找到匹配的catch子句后,程序会调用terminate函数终止程序

4.如果找到匹配的catch子句处理后,catch子句代码会继续执行

以下为代码的示例:

double Divide(int a,int b)    

{

    try

     { 

          if(b==0)

          {

                string s("Divide by zer0 condition") ;

                throw s;

          }

          else

          {

              return((double)a/(double)b);

          }

     }

     catch(int errid)

     {

              cout << errid << endl;

     }
}

void Func()        

{  

    int len,time;

    cin>>len>>time;

    try

    {

         cout << Divide(len,time)<<endl;

    }

    catch(const char*errmsg)

    {

          cout<<errmsg<<endl;

    }

 cout <<__FUNCTION__<<":" << __LINE__ << "⾏执⾏" << endl;

}

 

int main()

{
    while(1)

    {
        try

        {

                Func();

        }

        catch(const string& errmsg)

        {

            cout << errmsg << endl;

        }

}

   return 0;

 }

 上面代码从divide到func()最后到main()就是一个调用链

   1.4 查找匹配的处理代码 

1.如果抛出对象和多个catch的类型是匹配的,选择离抛出对象位置最近的那一个。

2.但是也有一些例外,就是权限缩小,例如:允许从非常量向常量的类型转换,允许数组转换成指向数组元素类型的指针等

3.如果到了main函数时依然没有找到合适的catch函数此时又不希望程序终止,此时在main函数中会使用catch(...),它可以捕捉任意类型的异常从而避免程序的终止,但有一个缺点就是不知道异常错误是什么。

    1.5 异常重新抛出

有时catch到一个异常对象后,需要对错误进行分类,其中的某种错误需要进行特殊的处理,其他错误则重新抛出异常给外层调用链处理。捕获异常后需要重新抛出,直接throw,就可以把捕获的对象直接抛出。

      1.6 异常安全问题

    异常抛出后,后面的代码就不再执行了,这就会导致有些前面申请了的资源到后面就无法被释放从而导致了资源资源的泄漏,而此时我们要做到捕获异常,释放资源后再重新抛出。

下面的代码为一个示例:

double Divide(int a,int b)

{
    if(b==0)

    {

           throw "Division by zero condition!";

    }

    return (double)a/(double)b;

}

 void Func()

{
   int* array = new int[10];

   try

   {

          int len,time;

          cin>>len>>time;

          cout<<Divide(len,time)<<endl;

   }

   catch(...)

   {

      cout <<"delete []" <<endl;

      delete[] array;

      throw;

   }

      cout<<"delete []" << array <<endl;

      delete[] array;

  }

  int main()

{

    try

    {
          Func();

    }

    catch(const char*errmsg)

    {
         cout<< errmsg <<endl;

    }

    catch(const exception&e)

    {

        cout<< e.what()<<endl;

    }

    catch(...)

    {
        cout << "Unkown Exception" << endl;

    }

     return 0;

 }

        1.7 异常规范

1.对于用户和编译器而言,预先知道程序是否会抛出会助于简化调用函数的代码

2.在C++ 11中函数列表后面加noexcept表示不会抛出异常吗,啥都不加就可能会抛出异常

3.加了noexcept保证不抛出异常,如果抛出异常了程序就会调用terminate终止程序

double Divide(int a,int b)noexcept

{

     if(b==0)

    {

         throw"Diviaion by zero condition!";

    }

    return(double)a/(double)b;

}

2.标准库的异常

C++标准库定义了自己的一套异常继承体系库,基类是exception,所以我们日常写程序时,需要在主函数捕获exception即可,要获取异常信息,调用what函数,what是一个虚函数。

以下代码为C++标准库的异常的一套例子:

#include<iostream>
#include<exception>
using namespace std;
 
class arg_error :public exception
{
public:
    arg_error()
        :exception("第二个参数错误 不能为0", 1)
    {}
    
};
int add(int a, int b)
{
    if (b == 0)
    {
        arg_error arg;
        throw arg;
    }
    return a / b;
 
}
int main(void)
{
        int a, b, res;
    cout << "请输入要除的两个数" << endl;
    cin >> a >> b;
    try{
        res = add(a, b);
        cout << res<< endl;
    }
    catch (exception & p)
    {
        cout << p.what();
    }
        return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/919945.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Golang语言整合jwt+gin框架实现token

1.下载jwt go get -u github.com/dgrijalva/jwt-go2.新建生成token和解析token文件 2.1 新建common文件夹和jwtConfig文件夹 新建jwtconfig.go文件 2.2 jwtconfig.go文件代码 /* Time : 2021/8/2 下午3:03 Author : mrxuexi File : main Software: GoLand */ package jwtC…

河工oj(1101-1113)

1101 求组合数&#xff08;函数专题&#xff09; 代码 #include<bits/stdc.h> using namespace std;int fact(int n) {int res 1;while(n) {res * n--;}return res; } int main() {int m, k;cin >> m >> k;cout << fact(m)/fact(k)/fact(m-k) <&l…

07架构面试题

目录 一、关于合生元的面试题的架构分析的问题 1. 陈述两种方案的优劣 2. 在那些条件下&#xff0c;会选择哪一个方案 3. 你倾向那一种&#xff1f; 4. 如果要实施方案二的&#xff0c;准备步骤和流程 一、关于合生元的面试题的架构分析的问题 1. 陈述两种方案的优劣 方案…

递归:编程世界的奇妙魔法之旅

模块一&#xff1a;递归的神秘面纱 —— 初窥魔法之门 1. 递归的概念&#xff1a;神秘的魔法回响 &#x1f60e;嘿&#xff01;各位编程大侠们&#xff0c;今天咱们要来聊聊一个超级神奇的玩意儿 —— 递归。这递归啊&#xff0c;简直就是编程世界里神秘得不能再神秘的魔法回…

力扣题目总结

1.游戏玩法分析IV AC: select IFNULL(round(count(distinct(Result.player_id)) / count(distinct(Activity.player_id)), 2), 0) as fraction from (select Activity.player_id as player_idfrom (select player_id, DATE_ADD(MIN(event_date), INTERVAL 1 DAY) as second_da…

Ubuntu22.04LTS 部署前后端分离项目

一、安装mysql8.0 1. 安装mysql8.0 # 更新安装包管理工具 sudo apt-get update # 安装 mysql数据库&#xff0c;过程中的选项选择 y sudo apt-get install mysql-server # 启动mysql命令如下 &#xff08;停止mysql的命令为&#xff1a;sudo service mysql stop&#xff0…

(Linux)搭建静态网站——基于http/https协议的静态网站

简单了解nginx配置文件 1.下载并开启nginx服务 下载 [rootlocalhost ~]# dnf install nginx -y开启 [rootlocalhost ~]# systemctl restart nginx 1.(1)搭建静态网站——基于http协议的静态网站 实验1&#xff1a;搭建一个web服务器&#xff0c;访问该服务器时显示“hello w…

vue3:scss引用

原文查看&#xff1a;https://mp.weixin.qq.com/s?__bizMzg3NTAzMzAxNA&mid2247484356&idx2&sn44b127cd394e217b9e3c4eccafdc0aa9&chksmcec6fb1df9b1720b7bd0ca0b321bf8a995fc8cba233deb703512560cbe451cfb1f05cdf129f6&token1776233257&langzh_CN#rd…

Oracle - 多区间按权重取值逻辑 ,分时区-多层级-取配置方案(二)

Oracle - 多区间按权重取值逻辑 &#xff0c;分时区-多层级-取配置方案https://blog.csdn.net/shijianduan1/article/details/133386281 某业务配置表&#xff0c;按配置的时间区间及组织层级取方案&#xff0c;形成报表展示出所有部门方案的取值&#xff1b; 例如&#xff0…

13.C++内存管理2(C++ new和delete的使用和原理详解,内存泄漏问题)

⭐本篇重点&#xff1a;new, delete的使用和原理 ⭐本篇代码&#xff1a;c学习/04.c-动态内存管理 橘子真甜/c-learning-of-yzc - 码云 - 开源中国 (gitee.com) 目录 一. new和delete的使用 1.1 操作内置类型 1.2 操作自定义类型 二. new, delete与malloc, free的区别 2.1…

用源码编译虚幻引擎,并打包到安卓平台

用源码编译虚幻引擎&#xff0c;并打包到安卓平台 前往我的博客,获取更优的阅读体验 作业内容: 源码编译UE5.4构建C项目&#xff0c;简单设置打包到安卓平台 编译虚幻 5 前置内容 这里需要将 Epic 账号和 Github 账号绑定&#xff0c;然后加入 Epic 邀请的组织&#xff0c…

golang通用后台管理系统09(系统操作日志记录)

1.日志工具类 package log/**** 日志记录 wangwei 2024-11-18 15:30*/ import ("log""os""path/filepath""time" )// 获取以当前日期命名的日志文件路径 func getLogFilePath() string {currentDate : time.Now().Format("2006-…

基于yolov8、yolov5的电塔缺陷检测识别系统(含UI界面、训练好的模型、Python代码、数据集)

摘要&#xff1a;电塔缺陷检测在电力设备巡检、运行维护和故障预防中起着至关重要的作用&#xff0c;不仅能帮助相关部门实时监测电塔运行状态&#xff0c;还为智能化检测系统提供了可靠的数据支撑。本文介绍了一款基于YOLOv8、YOLOv5等深度学习框架的电塔缺陷检测模型&#xf…

论文阅读 SeedEdit: Align Image Re-Generation to Image Editing

目录 摘要 1 INTRODUCTION 2 SEEDEDIT 2.1 T2I MODEL FOR EDITING DATA GENERATION 2.2 CAUSAL DIFFUSION MODEL WITH IMAGE INPUT 2.3 ITERATIVE ALIGNMENT 3 EXPERIMENTS 3.1 BENCHMARK AND METRICS 3.2 IMAGE EDITING COMPARISON 4 CONCLUSION 摘要 SeedEdit&…

昇思MindSpore第四课---GPT实现情感分类

1. GPT的概念 GPT 系列是 OpenAI 的一系列预训练模型&#xff0c;GPT 的全称是 Generative Pre-Trained Transformer&#xff0c;顾名思义&#xff0c;GPT 的目标是通过Transformer&#xff0c;使用预训练技术得到通用的语言模型。和BERT类似&#xff0c;GPT-1同样采取pre-trai…

Nacos实现IP动态黑白名单过滤

一些恶意用户&#xff08;可能是黑客、爬虫、DDoS 攻击者&#xff09;可能频繁请求服务器资源&#xff0c;导致资源占用过高。因此我们需要一定的手段实时阻止可疑或恶意的用户&#xff0c;减少攻击风险。 本次练习使用到的是Nacos配合布隆过滤器实现动态IP黑白名单过滤 文章…

STM32芯片EXIT外部中断的配置与原理以及模板代码(标准库)

配置EXIT外部中断其实就是把GPIO刀NVIC的各个外设配置好 第一步&#xff1a;配置RCC&#xff0c;把我们涉及到的外设的时钟都打开 &#xff08;此处EXTI是默认打开的&#xff0c;而NVIC是内核外设无需配置&#xff09; 第二步&#xff1a;配置GPIO,选择端口为输入模式 第三…

大数据实验4-HBase

一、实验目的 阐述HBase在Hadoop体系结构中的角色&#xff1b;能够掌握HBase的安装和配置方法熟练使用HBase操作常用的Shell命令&#xff1b; 二、实验要求 学习HBase的安装步骤&#xff0c;并掌握HBase的基本操作命令的使用&#xff1b; 三、实验平台 操作系统&#xff1…

商用密码产品认证名录说明

《商用密码产品认证目录》是为贯彻落实《中华人民共和国密码法》&#xff0c;进一步健全完善商用密码产品认证体系&#xff0c;更好满足商用密码产业发展需要&#xff0c;根据《国家密码管理局 市场监管总局关于调整商用密码产品管理方式的公告》《市场监管总局 国家密码管理局…

uniapp微信小程序接入airkiss插件进行WIFI配网

本文可参考uniapp小程序插件 一.申请插件 微信公众平台设置页链接&#xff1a;微信公众平台 登录您的小程序微信公众平台&#xff0c;进入设置页&#xff0c;在第三方设置->插件管理->添加插件中申请AiThinkerAirkissforWXMini插件&#xff0c;申请的插件appId为【wx6…