从零开始学C++之异常(三):异常与继承、异常与指针、异常规格说明

2023-10-27

一、异常与继承
如果异常类型为C++的类,并且该类有其基类,则应该将派生类的错误处理程序放在前面,基类的错误处理程序放在后面

#include <iostream>
#include <string>

using namespace std;

class MyException
{
public:
    MyException(const char *message)
        : message_(message)
    {
        cout << "MyException ..." << endl;
    }
    MyException(const MyException &other) : message_(other.message_)
    {
        cout << "Copy MyException ..." << endl;
    }
    virtual ~MyException()
    {
        cout << "~MyException ..." << endl;
    }

    const char *what() const
    {
        return message_.c_str();
    }
private:
    string message_;
};

class MyExceptionD : public MyException
{
public:
    MyExceptionD(const char *message)
        : MyException(message)
    {
        cout << "MyExceptionD ..." << endl;
    }
    MyExceptionD(const MyExceptionD &other)
        : MyException(other)
    {
        cout << "Copy MyExceptionD ..." << endl;
    }
    ~MyExceptionD()
    {
        cout << "~MyExceptionD ..." << endl;
    }
};

int main(void)
{
    try
    {
        MyExceptionD e("test exception");
        throw e;
    }
    catch (MyExceptionD &e)
    {
        cout << "catch MyExceptionD ..." << endl;
        cout << e.what() << endl;
    }
    catch (MyException &e)
    {
        cout << "catch MyException ..." << endl;
        cout << e.what() << endl;
    }

    return 0;
}

这里写图片描述
派生类的异常能够被基类所捕获,且前面的异常处理程序能够匹配的话首先catch,如果把基类的放在最前面,而且不是引用的形式,如 catch (MyException e); 那么将会被这个所catch 到,而且在构造e 的过程会有object slicing 的问题。

二、异常与指针
抛出指针通常是一个坏主意,因为抛出指针要求在对应处理代码存在的任意地方都存在指针所指向的对象(注意此时throw抛出时复制的是指针本身,不会去复制指针指向的内容)

int main(void)
{
    try
    {
        //MyExceptionD e("test exception");
        //throw &e;
        throw new MyExceptionD("test exception");
    }
    /*catch (void* e)
    {
        cout<<"catch void* ..."<<endl;
        cout<<((MyExceptionD*)e)->what()<<endl;
        delete (MyExceptionD*)e;
    }*/
    catch (MyExceptionD *e)
    {
        cout << "catch MyExceptionD ..." << endl;
        cout << e->what() << endl;
        delete e;
    }
    catch (MyException &e)
    {
        cout << "catch MyException ..." << endl;
        cout << e.what() << endl;
    }

    return 0;
}

这里写图片描述
其中MyException, MyExeptionD类如上所示,现在MyExeptionD 对象是在堆上分配的,所以在catch 的时候还没释放,还可以访问到
e->what(); 但需要自己在catch 末尾delete e; 假设将 throw new MyExceptionD(“test exception”); 换成
MyExceptionD e(“test exception”);
throw &e;
即抛出局部对象的指针,由于在catch 时MyExeptionD 对象已经被析构了,所以访问不到e->what(); 即e是空悬指针。
还有一点是,任何类型的指针都能被void* 指针所捕获,如果将catch (void* e);注释打开,那么由于排在前面,异常首先将被它所捕获。

三、异常规格说明
1、异常规格说明的目的是为了让函数使用者知道该函数可能抛出的异常有哪些。
可以在函数的声明中列出这个函数可能抛掷的所有异常类型。
例如:
void fun() throw(A,B,C,D);
2、若无异常接口声明,则此函数可以抛掷任何类型的异常。
3、不抛掷任何类型异常的函数声明如下:
void fun() throw();

void fun(int n) throw (int, MyException, MyExceptionD)
{
    if (n == 1)
    {
        throw 1;
    }
    else if (n == 2)
    {
        throw MyException("test Exception");
    }
    else if (n == 3)
    {
        throw MyExceptionD("test ExceptionD");
    }

}

void fun2() throw()
{

}

int main(void)
{
    try
    {
        fun(2);
    }

    catch (int n)
    {
        cout << "catch int ..." << endl;
        cout << "n=" << n << endl;
    }
    catch (MyExceptionD &e)
    {
        cout << "catch MyExceptionD ..." << endl;
        cout << e.what() << endl;
    }
    catch (MyException &e)
    {
        cout << "catch MyException ..." << endl;
        cout << e.what() << endl;
    }

    return 0;
}

这里写图片描述
实际上编译会产生警告:
warning C4290: 忽略 C++ 异常规范,但指示函数不是 __declspec(nothrow)
就是说VC++编译器现在还不怎么支持异常规格说明,举个例子说,void fun(int n) throw (int, MyException, MyExceptionD); 没有声明double 类型的异常,但在函数内throw 1.0; 在外部catch (double) 还是会成功。

四、C++标准库异常层次
这里写图片描述
比如dynamic_cast 执行错误会产生bad_cast 异常,new 分配内存错误会产生bad_alloc 异常,其实这些异常类都继承自exception类,但内部的实现都

没有有效的代码,只是用来标识当前程序产生了哪种类型的异常而已。

参考:
C++ primer 第四版
Effective C++ 3rd
C++编程规范

转载自http://blog.csdn.net/jnu_simba/article/details/9346155

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从零开始学C++之异常(三):异常与继承、异常与指针、异常规格说明 的相关文章

  • 虚拟数字人详解|有个性、有情感的对话技术探索

    文 蔡华 华院计算 元宇宙是当前流行的的技术和商业热点 而其背后的核心技术是数字人 近日 华院计算算法研究员蔡华博士就虚拟数字人 有个性 有情感的对话技术 的话题进行了讲解 以下内容为蔡华博士的演讲内容节选 虚拟数字人的三重 境界 关于虚拟
  • STM32编译生成的BIN文件详解

    背景 在做stm32的IAP功能 大概思路参见我的另一篇文章 跟别人讨论了关于app中发生中断之后流程的问题 然后看了一下BIN文件格式 主要是因为BIN文件就是镜像 不包含任何其他信息 如下载的地址等 就是对ROM的绝对描述 可以很清楚看
  • 安卓端自行实现工信部要求的隐私合规检测一(教你手写Xposed模块代码)

    前言 友情提示 文章较长 源码及相关使用教程都在文尾 之所以写这篇文章 是因为不久前 我们公司上架的app被打回来了 信通院那边出了个报告 里面说我们app未经授权就自动获取了手机的mac地址 当时其实是有点懵逼的 因为合规措施其实是已经做
  • 七十九.找出唯一成对的数(位运算)

    1 N 这N个数放在含有N 1个元素的数组中 只有唯一的一个元素值重复 其它均只出现一次 每个数组元素只能访问一次 设计一个算法将它找出来 不用辅助存储空间 能否设计一个算法实现 import java util Random public
  • 引力搜索算法

    最近在论文中看到有学者用改进的引力搜索算法解优化问题 有一个较好的效果 于是去了解了一下这个算法 引力搜索算法 Gravitational Search Algorithm GSA 是Esmat Rashedi等人在2009年提出的一种随机
  • 微信小程序——前端——抵扣券、优惠券样式

    微信小程序 前端 抵扣券 优惠券样式 效果图 实现思路 左边 划线 右边 使用信息 分割线 使用限制 整体底色 wrapper margin 0 auto width 100 display flex background linear g
  • 程序,进程和线程

    注 并发和并行是有区别的 并发是在同一时间段内同时运行 本质上还没有同时 而并行则是在同一时刻同时运行 一 程序 进程和线程之间的关系 1 一个应用程序是由许多个程序段组成 2 进程是由程序段 相关的数据段和PCB 进程控制块 组成 进程是
  • Java中“附近的人”实现方案讨论及代码实现

    在我们平时使用的许多app中有附近的人这一功能 像微信 qq附近的人 哈罗 街兔附近的车辆 这些功能就在我们日常生活中出现 像类似于附近的人这一类业务 在Java中是如何实现的呢 本文就简单介绍下目前的几种解决方案 并提供简单的示例代码 注
  • 46 最佳实践-性能最佳实践-内存大页

    文章目录 46 最佳实践 性能最佳实践 内存大页 46 1 概述 46 2 操作指导 46 最佳实践 性能最佳实践 内存大页 46 1 概述 相比传统的4K内存分页 openEuler也支持2MB 1GB的大内存分页 内存大页可以有效减少T
  • failed with initial frozen solve. Retrying with flexible solve. 什么意思?

    这通常是指一个软件包管理器 如pip conda等 在尝试安装某个软件包时遇到了问题 并且在第一次尝试使用 frozen solve 方法时失败了 Frozen solve 是一种求解器的方法 它会尝试使用已知的软件包版本和其依赖项版本来解

随机推荐

  • AD如何快速更改元件库器件的颜色

    如何你想在原理图库中快速修改元件的颜色 一根根线去点肯定是太慢了 可能第一反应就是查找相似 把颜色不是目标颜色全部选中 然后统一更改 但是在原理图库中 这一做法是行不通的 例如下图 可以在右上方找到筛选器 先选中Lines改成自己想要的颜色
  • 计算机网络思维导图

    计算机网络思维导图 按照计算机网络的TCP IP四层模型构建 物理层对应网络接口层的功能 这个是之前期末考试时做的思维导图 现在复习专业课发现里面还有很多缺漏 希望大家多多提意见 后期有时间我也会查漏补缺的 谢谢支持 目录 计算机网络思维导
  • 集成运算放大电路实验报告_模电总结:第三章、集成运算放大电路

    我的公众号 每日晴天 可关注领取我的笔记pdf版哦 部分英文 d差模 different 差模的d c 共模 common mode 3 1多级放大电路 1 多级放大电路的组成 输入级 输入电阻高 噪声和漂移小 中间级 具有足够大的放大能力
  • android httpClient 支持HTTPS的2种处理方式

    项目中Android https或http请求地址重定向为HTTPS的地址 相信很多人都遇到了这个异常 无终端认证 javax net ssl SSLPeerUnverifiedException No peer certificate 1
  • YoloV4训练自己的数据集

    YoloV4训练自己的数据集 1 建立工作文件夹 2 准备训练数据集 3 修改配置文件 4 Anchor Box先验框聚类分析与修改 5 训练自己的数据集 6 测试训练出来的网络模型 7 性能统计 1 建立工作文件夹 新建一个项目文件夹 用
  • STM32/AMP32F407进入低功耗待机模式后立马被唤醒的解决办法

    最近项目用到低功耗 但是调试发现进入待机就被唤醒的问题 清除WU SB两个唤醒标志位 也依然被立马唤醒一次 进入待机模式 HAL PWR EnterSTANDBYMode 通过极海的数据手册终于发现 我们在使能WAKE UP PA 0唤醒脚
  • 【Linux】进程描述符

    linux进程管理 1 进程描述符 进程描述符 Linux使用进程描述符数据结构记录现场信息 然后给予进程描述符管理进程 包括进程的创建 调度 消亡等操作 进程除了包括运行着的程序 还包括系统资源 当前CPU现场 调度信息 进程间关系等 记
  • One PUNCH Man——激活函数和梯度消失/爆炸

    文章目录 什么是激活函数 激活函数介绍 梯度消失 爆炸 首先推荐一个写公式的网站 https private codecogs com latex eqneditor php 什么是激活函数 如下图 在神经元中 输入的 inputs 通过加
  • FlatBuffers在Java中的使用

    1 去maven仓库下载官网库flatbuffers java 1 7 0 1 jar 地址 点击打开链接 2 编写fbs文件 chat fbs namespace Proto 聊天频道 enum ChatChannel byte SYST
  • 利用Logstash plugins做更多的事情

    1 引言 之前一篇文章 Logstash 介绍及linux下部署 我们实现了logstash的安装以及简单的控制台标准输入输出测试 那么logstash能不能做更多的事情呢 答案是肯定的 logstash就是为了处理日志数据而生的 一个最直
  • mysql下出现Unknown column 'xx' in 'on clause'的完全解决方法

    mysql下出现Unknown column xx in on clause 的完全解决方法 在项目中执行查询无结果 在数据库运行sql报错 Unknown column xx in on clause 百度过后找到这个文章并完全解决了问题
  • 欠拟合和过拟合

    过拟合 定义 具体表现就是最终模型在训练集上效果好 在测试集上效果差 模型泛化能力弱 具体表现就是最终模型在训练集上效果好 在测试集上效果差 模型过于复杂 过拟合的原因 训练数据中噪音干扰过大 使得学习器认为部分噪音是特征从而扰乱学习规则
  • Nginx二级项目配置

    Nginx二级项目服务页面部署 应用场景 比如一个项目需要一个正常的生产服务的地址在根目录 现在需要一个后台管理项目可以部署在 admin 的路径下 需要帮助文档的页面可以部署在 help nginx conf 配置 location ma
  • 【SQL注入-08】二次注入案例—以sqli-labs-less24为例

    目录 1 二次注入概述 1 1 定义 1 2 思路 2 二次注入案例 2 1 实验平台 2 2 实验目标 2 3 具体注入过程 2 3 1 注入前准备 2 3 2 确定目标账户admin 2 3 3 第一次注入 2 3 4 第二次注入 2
  • eos bp节点 超级节点搭建

    https github com nebulaprotocol 这个网址里面有一个 fake terminal website 比较有意思 可以看看示例 https bp nebulaprotocol com 搭建eos BP节点 环境搭建
  • 家政服务小程序制作攻略揭秘

    想要打造一个家政服务小程序 但是又不懂编程和设计 不用担心 下面将为你详细介绍如何利用第三方平台 从零开始打造一个家政服务小程序 首先 你需要找到一个适合的第三方平台 例如乔拓云网 在乔拓云网的 轻应用小程序 中 点击 去管理 你就可以进入
  • 回顾2021,展望2022

    2021 这一年最大的收获是孕育了一个聪明漂亮机灵的小家伙 这一年我虚岁28岁 和爱的人有了爱的结晶 东哥各方面都挺好的 我们都不是圣人 都是能力有限的普通人 但他在尽其所能的对我好 我不是万能的人 但也独立坚强 之后一个人带娃的日子适应的
  • LaTeX公式中指定某些字母或符号为正体

    m rm G 显示效果为
  • I/O 函数/缓存和字节流、占位符、getchar(),putchar()

    I O 函数 C 语言提供了一些函数 用于与外部设备通信 称为输入输出函数 简称 I O 函数 输入 import 指的是获取外部数据 输出 export 指的是向外部传递数据 缓存和字节流 严格地说 输入输出函数并不是直接与外部设备通信
  • 从零开始学C++之异常(三):异常与继承、异常与指针、异常规格说明

    一 异常与继承 如果异常类型为C 的类 并且该类有其基类 则应该将派生类的错误处理程序放在前面 基类的错误处理程序放在后面 include