C++指针对象和异常(10)

news2024/11/18 17:26:32

异常(exception)

为什么有异常

异常在C++用于错误处理,C语言中一般使用返回值表示错误,C++对错误处理进行了扩展,统一使用异常机制来处理程序中发生的错误。

C++的异常处理包括两个部分 ----- 抛出异常和捕获异常,如果抛出的异常被捕获,处理完之后程序会继续运行,如果抛出的异常未被捕获,将导致程序终止。

异常的抛出和捕获

异常抛出 ------- throw

throw是用于抛出异常的关键字,用法如下:

throw 异常(对象);

在函数声明中应该指定可能抛出的异常,应该在函数声明指定。

void show();//该函数可能抛出任何异常 void show()throw();//该函数不抛出任何异常 void show()throw(char,int);//该函数可能抛出char和int型异常

/*03-异常的抛出和捕获*/
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

class A {
public:
    //不抛出任何异常
    void show()throw()
    {
        cout << "show A" << endl;
    }
};

//foo函数可能抛出int,double,const char *,A *类型的异常
void foo()throw(int, double, const char*)
{
    srand(time(0));
    int s = rand() % 4;//0 1 2 3 4

    cout << "foo start!" << endl;

    if (s == 0) {
        cout << "正常运行!" << endl;
    }
    else if (s == 1) {
        //抛出int型异常
        throw 1;
    }
    else if (s == 2) {
        //抛出double型异常
        throw 3.14;
    }
    else if (s == 3) {
        //排除const char *型异常
        throw "起火了";
    }
    cout << "foo finished!" << endl;
}

int main()
{
        foo();
        cout << "after foo!" << endl;
  
    //vs会报错,抛出后没有处理
    cout << "app finished!" << endl;
    return 0;
}

异常的捕获 ---------- try…catch

捕获异常使用try…catch关键字,用法如下:

try{ //可能抛出异常的代码 }catch(异常类型1 变量){//根据类型捕获异常 //处理异常类型1的代码 }catch(异常类型2 变量){//根据类型捕获异常 //处理异常类型2的代码 //throw 变量 ----- 继续向上一层抛出 }… //… //异常被捕获后,执行对应的异常处理代码,然后继续执行try…catch之后的代码 //异常未被捕获,仍然导致程序终止 //捕获异常后,如果当前无法处理,可以继续抛出

/*03-异常的抛出和捕获*/
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

class A {
public:
    //不抛出任何异常
    void show()throw()
    {
        cout << "show A" << endl;
    }
};

//foo函数可能抛出int,double,const char *,A *类型的异常
void foo()throw(int, double, const char*, A*)
{
    srand(time(0));
    int s = rand() % 5;//0 1 2 3 4

    cout << "foo start!" << endl;

    if (s == 0) {
        cout << "正常运行!" << endl;
    }
    else if (s == 1) {
        //抛出int型异常
        throw 1;
    }
    else if (s == 2) {
        //抛出double型异常
        throw 3.14;
    }
    else if (s == 3) {
        //排除const char *型异常
        throw "起火了";
    }
    else if (s == 4) {
        //排除A *型异常
        throw new A;
    }

    cout << "foo finished!" << endl;
}

int main()
{
    try {
        foo();
        cout << "after foo!" << endl;
    }
    catch (int e) {//捕获int异常
        cout << "捕获到了int型异常=" << e << endl;
    }
    catch (double e) {//捕获double异常
        cout << "捕获到了double型异常=" << e << endl;
    }
    catch (const char* e) {//捕获const char *异常
        cout << "捕获到了const char *型异常=" << e << endl;
        cout << "无法处理,继续抛出" << endl;
        throw e;
    }
    catch (A* e) {//捕获A *异常
        cout << "捕获到了A *型异常" << endl;
        e->show();
        delete e;
    }

    cout << "app finished!" << endl;
    return 0;
}

练习:

实现捕获A *类型的异常,同时调用该异常的show函数。

异常的层次设计

image-20220721225630132

异常处理的原则是分层次捕获和处理,捕获到了本层的异常就直接处理返回 捕获到了不属于本层的异常就继续抛出

系统预定义异常

C++中预定义类一些异常,为C++预定义的类和函数(string cin cout new…)服务,在编程中可以直接使用。

预定义的异常类都是exception的子类/间接子类,当调用C++预定义类中的成员函数和预定义的全局函数时,可能抛出这些异常。

image-20220721225425551

使用C++预定义异常需要包含头文件

 #include <stdexcept>              

exception类中有一个虚函数 ----- what(),该函数返回异常原因的字符串

用户自定义异常

在C++项目开发中,详细设计时应该设计好异常的框架,通常的做法就是定义一个异常的基类,项目中所有的异常都是该类的子类/间接子类。

在代码中根据条件抛出异常

在函数语句中抛出

在执行可能排除异常的代码时捕获异常

try{ //… }catch(…){ //… }… //根据不同的异常进行不同的处理

注意:如果代码可能抛出的异常中有多态性的父子关系,捕获异常时必须先捕获子类异常,再捕获父类异常。

练习:

1.为MyArray类添加一个at成员函数,该函数可能抛出out_of_range的异常;

int &at(size_t n) { }

构造函数可能抛出bad_alloc异常。

在使用该类的代码中捕获这些异常。

作业:

1.扩展自定义异常的代码(dms_exception)

添加 服务器无响应的异常子类/服务器资源不足异常子类 继承 服务器异常类 添加 客户端网络无连接的异常子类/客户端发送数据越界异常子类 继承 客户端异常类

在send_data函数函数抛出这些异常,在主函数中捕获。

/*dms_exception.h*/
#ifndef DMS_EXCEPTION_H
#define DMS_EXCEPTION_H

#include <string>
using namespace std;

//异常的基类
class dms_exception {
public:
    dms_exception(string msd = "dms exception")throw();
    //声明what方法
    virtual string what()throw();

private:
    string description; //描述
};

//服务器异常子类
class dms_server_exception :public dms_exception {
public:
    dms_server_exception(string msg = "server exception")throw();
};

//客户端异常子类
class dms_client_exception :public dms_exception {
public:
    dms_client_exception(string msg = "client exception")throw();
};

#endif // DMS_EXCEPTION_H
/*dms_exception.cpp*/
#ifndef DMS_EXCEPTION_H
#define DMS_EXCEPTION_H

#include <string>
using namespace std;

//异常的基类
class dms_exception {
public:
    dms_exception(string msd = "dms exception")throw();
    //声明what方法
    virtual string what()throw();

private:
    string description; //描述
};

//服务器异常子类
class dms_server_exception :public dms_exception {
public:
    dms_server_exception(string msg = "server exception")throw();
};

//客户端异常子类
class dms_client_exception :public dms_exception {
public:
    dms_client_exception(string msg = "client exception")throw();
};

#endif // DMS_EXCEPTION_H
/*main.cpp
*/
#include <iostream>
#include <cstdlib>
#include <ctime>

#include "dms_exception.h"

using namespace std;

//dms系统发送数据接口 ------ 服务器异常 客户端异常 ...
void send_data()
{
    srand(time(0));
    int r = rand() % 4;

    if (r == 0) {
        cout << "发送成功" << endl;
    }
    else if (r == 1) {//服务器异常
        throw dms_server_exception("dms服务器异常");
    }
    else if (r == 2) {//客户端异常
        throw dms_client_exception("dms客户端异常");
    }
    else if (r == 3) {//其他异常
        throw dms_exception("dms其他异常");
    }

}

int main()
{
    //执行可能抛出异常的代码
    try {
        send_data();
    }
    catch (dms_server_exception& e) {
        cout << "服务器异常" << endl;
        cout << e.what() << endl;
    }
    catch (dms_client_exception& e) {
        cout << "客户端异常" << endl;
        cout << e.what() << endl;
    }
    catch (dms_exception& e) {
        cout << "其他异常" << endl;
        cout << e.what() << endl;
    }

    return 0;
}

项目代码地址

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

BW生成HANA视图权限配置

目录 1 操作步骤1.1 SAP HANA端1、创建用户2、常规信息3、配置角色4、配置系统权限5、配置对象权限 1.2 BW端1、SM30配置数据库连接参数2、SU01创建账户&#xff08;与SAP HANA数据库账户名一致&#xff09;3、使用RS2HANA_VIEW查看配置Assignment TypeDB Connection NameLimit…

如何解决亚马逊、ebay砍单、封号问题?稳定测评方案分析

很多卖家和工作室朋友询问我为什么在测评过程中经常遇到砍单和封号的问题。实际上&#xff0c;这并不难理解&#xff0c;因为测评所涉及的技术问题很多&#xff0c;并不能仅通过解决IP或环境的单一因素来实现稳定的测评。 目前市面上存在许多技术方案&#xff0c;例如指纹浏览…

火山引擎Dataleap治理实践:如何降低数仓建设成本

背景 存储与计算资源是数仓建设的基础&#xff0c;也是数仓建设中的重要成本支出。而随着数仓建设规模逐渐扩大、时间跨度逐渐拉长&#xff0c;将不可避免的出现数据表、任务、字段的冗余。为了减轻资源负担&#xff0c;降低数仓维护成本&#xff0c;需要对数仓建设成本进行治…

微信小程序-上传代码失败,提示分包大小超过限制

开发者可通过开发者工具中的性能扫描工具提前发现代码中的可优化项&#xff1a; 1. 代码包不包含插件大小超过 1.5 M 【建议】小程序代码包单个包大小限制为2M。因此我们建议开发者在开发时&#xff0c;如果遇到单包体积大于1.5M的情况&#xff0c;可以采取分包的方式&#x…

Star History 月度开源精选|2023 年 5 月

收集完五月的 Star History 精选之后我们惊讶地发现居然有那么多好玩好用的项目&#xff0c;无论是低代码&#xff0c;或是可以帮你少写代码&#xff0c;即便不是专业开发者也可以上手了&#xff01; Windmill Windmill 可以看做是 Airplane 的开源替代品 / Temporal 的低代码…

安科瑞产品在泛在电力物联网的应用

安科瑞虞佳豪 泛在电力物联网是以通讯技术为基础发展而来的新型物联网体系&#xff0c;其构建的核心是满足电网能源系统的智能判断和自适应调节能力&#xff0c;这将提高能源的替代和利用能力。对于电力物联网来说&#xff0c;通讯技术是其核心的技术内容之一&#xff0c;也是…

直播平台中的美颜SDK技术探究

而在直播过程中&#xff0c;美颜技术的应用已经成为了不可或缺的一部分。美颜技术能够让主播在镜头前变得更加漂亮自信&#xff0c;也能够提高直播的观看体验。在直播平台中&#xff0c;美颜SDK技术的探究就显得尤为重要。 一、美颜SDK技术的定义 美颜SDK技术是一种通过算法…

Java中的增强 for 循环 foreach

foreach 是 Java 中的一种语法糖&#xff0c;几乎每一种语言都有一些这样的语法糖来方便程序员进行开发&#xff0c;编译期间以特定的字节码或特定的方式来对这些语法进行处理。能够提高性能&#xff0c;并减少代码出错的几率。在 Java 中还有比如 泛型、自动拆箱、自动装箱、内…

【集合数据类型详解】——基础语法

目录索引 集合特点&#xff1a;集合用处&#xff1a;去重操作&#xff1a; 创建集合&#xff1a;实例&#xff1a;实例2&#xff1a; 集合运算&#xff1a;交集&#xff1a;并集&#xff1a;补集&#xff1a;差集&#xff1a; 集合特点&#xff1a; 同一集合中&#xff0c;只能…

ssm酒店住宿预定系统-计算机毕设 附源码 87020

ssm酒店住宿预定系统 目 录 摘要 1 绪论 1.1 研究背景 1.2开发意义 1.3ssm框架 1.4论文结构与章节安排 2 2 酒店住宿预定系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3数据删除流程 2.3 系统功能分析 2.3.1功能性分…

使用Servlet完成单表的增删改查功能以及使用模板方法设计模式解决类爆炸问题(重写service模板方法)

使用Servlet做一个单表的CRUD操作 开发前的准备 导入sql脚本创建一张部门表 drop table if exists dept; create table dept(deptno int primary key,dname varchar(255),loc varchar(255) ); insert into dept(deptno, dname, loc) values(10, XiaoShouBu, BeiJing); inser…

【读书笔记】《认知觉醒》- 周岭

不停的阅读&#xff0c;然后形成自己的知识体系。 2023.06.25 读 文章目录 自序 开启自我改变的原动力上篇 内观自己&#xff0c;摆脱焦虑第一章 大脑——一切问题的起源第一节 大脑&#xff1a;重新认识你自己三重大脑高低之分与权力之争成长就是克服天性的过程 自序 开启自我…

深度学习训练过程耗时越来越长解决方法

自己的情况是代码中有过多的图片显示&#xff0c;导致每个iteration/epoch训练时间越来越长。或其他类似的东西。 解决方法&#xff1a; 用plt.close()及时关闭图片 fig plt.figure(0) # 新图0 plt.savefig( ) # 保存 plt.close(0) # 关闭图0plt.close(all) #关闭所有图…

Kafka 入门到精通

消息队列的流派 什么是 MQ Message Queue&#xff08;MQ&#xff09;&#xff0c;消息队列中间件。很多人都说&#xff1a;MQ 通过将消息的发送和接收分离来实现应用程序的异步和解偶&#xff0c;这个给人的直觉是——MQ 是异步的&#xff0c;用来解耦的&#xff0c;但是这个只…

每日学术速递6.12

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.DynIBaR: Neural Dynamic Image-Based Rendering(CVPR 2023 Award Candidate) 标题&#xff1a;DynIBaR&#xff1a;基于神经动态图像的渲染 作者&#xff1a;Mengyuan Yan Jessi…

【2023,学点儿新Java-15】案例分享:基于Java实现餐厅点餐系统(附完整源代码)

前情回顾&#xff1a; 【2023&#xff0c;学点儿新Java-14】携程面试题&#xff1a;如何看待Java是一门半编译半解释型的语言&#xff1f;| 咨询互联网行业 资深前辈的一些问题 | 附&#xff1a;为什么说ChatGPT的核心算法是…&#xff1f;| GPT-3.5【2023&#xff0c;学点儿新…

通用密钥,无需密码,在无密码元年实现Passkeys通用密钥登录(基于Django4.2/Python3.10)

毋庸讳言&#xff0c;密码是极其伟大的发明&#xff0c;但拜病毒和黑客所赐&#xff0c;一旦密码泄露&#xff0c;我们就得绞尽脑汁再想另外一个密码&#xff0c;但记忆力并不是一个靠谱的东西&#xff0c;一旦遗忘密码&#xff0c;也会造成严重的后果&#xff0c;2023年业界巨…

算法程序设计 之 模糊数字、真假银币(1/8)

内容 模糊数字、真假银币 一、目的&#xff1a; 理解并掌握枚举算法的基本思想和设计步骤。 二、内容 1模糊数字 问题描述&#xff1a;一张单据上有一个5位数的编码&#xff0c;因为保管不善&#xff0c;其百位数已经变得模糊不清。但是知道这个5位数是57和67的倍数。现…

c++Qt Creator调用 python 完整版 + 解决bug过程

文章目录 创建项目配置python环境导入Python库其他坑点Python.h 头文件报错ModuleNotFoundError: No module named encodings’ 完美解决找不到python文件 成功&#xff01; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 创建项目 选择创建 qmake 项目&#xff1a; …

SciencePub学术 | 计算机类重点SCIEEI征稿中

SciencePub学术 刊源推荐: 计算机类重点SCIE&EI征稿中&#xff01;影响因子高&#xff0c;对国人友好&#xff01;信息如下&#xff0c;录满为止&#xff1a; 一、期刊概况&#xff1a; 计算机类重点SCIE&EI 【期刊简介】IF&#xff1a;8.0-8.5&#xff0c;JCR1区&am…