C++_22_异常
文章目录
- 异常
- 概念:
- **抛出异常:**
- 关键字:
- **捕获异常:**
- **栈解旋:**
- **异常的接口声明:**
- **异常对象的生命周期:**
- 1 传递异常对象
- 【不使用】
- 2 传递异常对象指针
- 【不使用】
- 3 传递异常对象引用
- 【**最优解**】
- **异常的多态:**
- 标准异常库:
- 自定义异常类:【了解】
- 最需注意的点:
- 拷贝构造
- 析构函数
- 必须手动回收
- 野指针与空指针
- 虚函数与纯虚函数
- 虚析构造与纯虚析构
- 类模版
异常
概念:
程序中因硬件或代码编写时考虑不足导致的程序崩溃
硬件问题: 不予处理
代码编写考虑不足: 要处理
分类:
- 编译时错误: 语法错误导致
运行时错误: 考虑不足导致
抛出异常:
关键字:
throw : 抛出
语法:
throw 数 据;
捕获异常:
语法:
try {} catch(数据类型1 变量名1) {} catch(数据类型2 变量名2) {} ......
示例:
#include <iostream> using namespace std; void myDiv(int n01, int n02) {//什么情况下抛出异常if (n02 == 0){// throw 1;throw 'a'; // 这里抛出的 就是catch 接收的值} } int main(int argc, char const *argv[]) {try{cout << "1111" << endl;myDiv(10, 0);cout << "222" << endl;}catch (int e){cout << "int 除0了" << endl;}catch (char e){cout << "char 除0了" << endl;}return 0; }
注意:
> 如果在try中出现异常,其try中剩余代码将不在执行,进入对应的catch中
> catch中变量的值就是抛出异常时throw后的数据
> catch可以有多个
栈解旋:
只能解旋栈区的东西 堆区的没戏 new的 都得自己去释放
概念:
> 当try中出现异常,其异常代码之上创建的对象都会被释放 > 其释放顺序与创建顺序相反 > 这种情况称为栈解旋注意:new创建的对象在堆区,无法自动释放
#include <iostream>
using namespace std;
class Data
{
public:Data() {cout << "构造函数" << endl; }~Data() { cout << "析构函数" << endl; }
};
class Data02
{public:Data02() { cout << " Data02 构造函数" << endl; }~Data02() { cout << " Data02 析构函数" << endl; }
};
int main(int argc, char const *argv[])
{try{//Data *d01 = new Data();//Data02 *d02 = new Data02();Data02 d02;Data d01;throw 1;}catch (int e){cout << "xxxx" << endl;}return 0;
}
异常的接口声明:
语法:
返回值类型 函数名(形参列表) throw (可能抛出的异常1 , 可能抛出的异常2 ,...) {函数体; }
注意:
如果 throw() 就是里面没东西
说明当前函数没用异常
throw() == noexcept 没有异常
// 异常的接口声明 #include <iostream> using namespace std; // 此时在VSCode会显示红色,但是语法没有问题 void myDiv(int x, int y) throw(int, char) {if (y == 0){throw 1;}cout << x / y << endl; } int main(int argc, char const *argv[]) {try{myDiv(10, 0);}catch (int e){}catch (char e){}return 0; }
异常对象的生命周期:
1 传递异常对象
【不使用】
缺点: 占用内存大
此时会触发拷贝构造,会形成一个新的异常对象,就得销毁这两个对象
示例:
#include <iostream> using namespace std; class MyException { public:MyException(){cout << "构造函数被调用" << endl;}MyException(const MyException &e){cout << "拷贝构造被调用" << endl;}~MyException(){cout << "析构函数被调用" << endl;} }; int main(int argc, char const *argv[]) {try{// MyException():创建了MyException的一个对象,该对象没有对象名,称为匿名对象throw MyException();}catch (MyException e){}return 0; }
2 传递异常对象指针
【不使用】
缺点:会造成内存泄漏
传递异常对象,创建一次 但是不销毁 因为没delete
#include <iostream> using namespace std; class MyException { public:MyException(){cout << "构造函数被调用" << endl;}MyException(const MyException &e){cout << "拷贝构造被调用" << endl;}~MyException(){cout << "析构函数被调用" << endl;} }; int main(int argc, char const *argv[]) {try{// 传递的是指针throw new MyException();}catch (MyException *e){}return 0; }
3 传递异常对象引用
【最优解】
传递异常对象引用,只会创建一次,而且可以自动销毁
示例:
#include <iostream> using namespace std; class MyException { public:MyException(){cout << "构造函数被调用" << endl;}MyException(const MyException &e){cout << "拷贝构造被调用" << endl;}~MyException(){cout << "析构函数被调用" << endl;} }; int main(int argc, char const *argv[]) {try{// 传递的是异常对象的引用throw MyException();}catch (MyException &e){}return 0; }
异常的多态:
注意:
1 抛出的子类异常,可以被父类异常类型接收 2 抛出的子类异常,catch 中 有父类异常与子类异常类型,此时按代码顺序书写接收,建议先子后父
示例
#include <iostream> // 异常的多态 using namespace std; class MyException {}; class NullException : public MyException {}; int main(int argc, char const *argv[]) {try{throw NullException();}catch (NullException &e){cout << "NullException" << endl;}catch (MyException &e){cout << "MyException" << endl;}return 0; }
标准异常库:
概述:
由c++提供的一套异常相关的类
自定义异常类:【了解】
步骤:
-
1 自定义异常类 使其继承于 exception 获得其子类
-
2 定义一个变量记录异常信息
-
3 定义该类的构造函数,拷贝构造,析构函数【只有析构需要判断是否为空,拷贝不用会重复释放野指针出现段错误】
-
4 重写 what 函数
const char* what() const noexcept {return 步骤2定义的变量 }
-
注意
编译使用需加 -std=c++11
最需注意的点:
拷贝构造
何时触发调用:
当 对象A以对象B进行初始化
如:
class Data {};
Data b; //创建对象
Data a = b; // 将b 赋值给a 对象b 以对象a进行初始化 就是a b 都是单独的method(Data d)
{
}
method(b);//Data d = b; 将 b 赋值 给 d 触发拷贝构造 Data method()
{static Data d;return d;
}
Data c = method();//Data c = d 将d 赋值给 c
析构函数
调用时机: 对象销毁前
- 生命周期
- 局部变量:随着所在的函数的调用而生成,随着所在函数的执行完毕而销毁
- 成员变量:随着所在的对象的创建而生成,随着所在的对象销毁而销毁
- 全局变量:随着所在的程序启动而生成,随着程序的关闭而销毁
- 静态局部变量:随着所在函数的第一次调用而生成,随着所在程序的执行完毕而销毁
- 静态成员变量:随着所在的类的加载而生成,随着所在程序的执行完毕而销毁
- 静态全局变量:随着所在的程序启动而生成,随着程序的关闭而销毁
堆区开辟的内存
必须手动回收
class Data
{
};
int *method()
{int *num = (int *)calloc(1, 4);char *str = (char *)calloc(50, 1);// Data d;Data *d = new Data();return num;
}
int main()
{int *p = method();
}
野指针与空指针
> 指针存储的地址是随机的 有可能指向 堆区 有可能指向栈区 或者其他区 是不可控的 因为栈区的会自动释放 所以当指向栈区的时候程序不报错 但是这是不可控的 > 空指针存储的地址是 NULL 注意:对象的成员变量的值默认为 随机数所以 一定注意 拷贝函数的时候不要判断是否不为空并释放因为 成员变量默认是随机数 所以就不是 空的 你一旦释放因为是随机的所以指针就是野指针 释放野指针就会触发重复释放的核心段错误 所以 写的时候 只有 析构的时候需要进行判断 而且要注意继承的情况
class Data { public:int x;char *str;Data() : x(0), str(NULL){}Data(int x, char *str) : x(x){int len = strlen(str) + 1;this->str = (char *)calloc(len, 1);strcpy(this->str, str);}Data(const Data &d){this->x = d.x;int len = strlen(d.str) + 1;this->str = (char *)calloc(len, 1);strcpy(this->str, d.str);}~Data(){if (str != NULL){free(str);str = NULL;}} }; Data d1; cout << d1.x << endl; Data d2(10, "张三");
虚函数与纯虚函数
虚函数:
有函数体,所在的类,可以创建对象,正常继承,子类重写父类虚函数,子类对象转换
为父类对象后调用该函数执行的子类重写的该函数
纯虚函数:没有函数体,所在的类不能直接创建对象,可以继承,但是子类要么也是抽
象类,要么重写其所有纯虚函数重写的纯虚函数也是虚函数
虚析构造与纯虚析构
-
应该释放的是父 放父 子也释放
-
放子 只释放了父 子本身没释放
类模版
class 类名 : public 父类名
{
private:成员变量
public:无参构造函数有参构造函数基本类型 用 = 指针类型 考虑要不要深拷贝 拷贝构造基本类型 用 = 指针类型考虑要不要深拷贝 virtual 析构函数释放深拷贝在堆区的空间get constset 特有函数
}
相关文章:

C++_22_异常
文章目录 异常概念:**抛出异常:**关键字: **捕获异常:****栈解旋:****异常的接口声明:****异常对象的生命周期:**1 传递异常对象【不使用】2 传递异常对象指针【不使用】3 传递异常对象引用【**…...

开源 AI 智能名片链动 2+1 模式 O2O 商城小程序在社群活动中的应用与时机选择
摘要:本文探讨了开源 AI 智能名片链动 21 模式 O2O 商城小程序在社群经济中的重要性,着重分析了如何借助该小程序适时举办大型活动以维持和引爆社群活跃度。通过对活动时机选择的研究,强调了针对社群用户量身定制活动时机的必要性,…...

从HarmonyOS升级到HarmonyOS NEXT-环信SDK数据迁移
2024年6月21日 HarmonyOS NEXT (后续称之为 NEXT) 正式发布,随着 NEXT 稳定版的逐渐临近,各个应用及SDK正在忙于适配 NEXT 系统,同样也面临着系统升级时如何对数据的迁移适配。本文通过使用环信 SDK 介绍如何从 Harmon…...

Spring Boot-Bean注入问题
在Spring Boot开发中,Bean的注入是核心概念之一,它确保了组件之间的依赖关系得以维护并方便管理。然而,在实际开发过程中,Bean的注入有时会出现问题 1. Spring Boot中的Bean注入 首先,了解Spring Boot中的Bean注入机…...

【在Linux世界中追寻伟大的One Piece】IP分片和组装的具体过程
目录 1 -> IP分片和组装的具体过程 2 -> 分片与组装的过程 2.1 -> 分片 2.2 -> 组装 3 -> 分片与组装的示意图 3.1 -> 分片组装场景 1 -> IP分片和组装的具体过程 16位标识(id):唯一的标识主机发送的报文。如果IP报文在数据链路层被分片…...

2024年中国研究生数学建模竞赛A/C/D/E题全析全解
问题一: 针对问题一,可以采用以下低复杂度模型,来计算风机主轴及塔架的疲劳损伤累积程度。 建模思路: 累积疲劳损伤计算: 根据Palmgren-Miner线性累积损伤理论,元件的疲劳损伤可以累积。因此,…...

【图虫创意-注册安全分析报告-无验证方式导致安全隐患】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…...

解决 npm ERR! node-sass 和 gyp ERR! node-gyp 报错问题
前言 在对一个项目进行npm i的时候 一直报错 npm ERR! code 1 npm ERR! path D:....\node-sass npm ERR! command failed 显示没有办法安装这个node-sass包 包兼容性 我电脑中默认使用的16的node版本,查找本地项目中这个包的版本和官方对于这个包的兼容ÿ…...

Golang | Leetcode Golang题解之第421题数组中两个数的最大异或值
题目: 题解: const highBit 30type trie struct {left, right *trie }func (t *trie) add(num int) {cur : tfor i : highBit; i > 0; i-- {bit : num >> i & 1if bit 0 {if cur.left nil {cur.left &trie{}}cur cur.left} else …...

每天一道面试题(15):谈谈你对CAS的理解
CAS(Compare And Swap)机制在并发编程中是一个非常重要的概念,主要用于实现原子性操作,避免使用传统的锁机制,从而提高性能。 CAS 的基本原理 CAS 的核心思想是通过比较当前值与预期值来决定是否执行修改。其流程如下…...

如何将MySQL卸载干净(win11)
相信点进来的你肯定是遇到了这个问题,那就是在安装MySQL的时候操作错误,最后结果不是自己想要的。卸载重新安装又发现安装不了。其实最主要的原因就是没有将MySQL卸载干净,那么如何把MySQL卸载干净?下面本篇文章就来给大家一步步介…...

【Linux】简易日志系统
目录 一、概念 二、可变参数 三、日志系统 一、概念 一个正在运行的程序或系统就像一个哑巴,一旦开始运行我们很难知晓其内部的运行状态。 但有时在程序运行过程中,我们想知道其内部不同时刻的运行结果如何,这时一个日志系统可以有效的帮…...

yum 集中式安装 LNMP
目录 安装 nginx 安装 mysql 安装 php 配置lnmp 配置 nginx 支持 PHP 解析 安装 nginx 修改yum源 将原本的yum源备份 vim /etc/yum.repos.d/nginx.repo [nginx-stable] namenginx stable repo baseurlhttp://nginx.org/packages/centos/7/$basearch/ gpgcheck0 enable…...

淘宝扭蛋机小程序,扭蛋机文化下的新体验
在数字化时代中,扭蛋机逐渐从传统的线下机器转移到了线上互联网中,市场得到了创新发展。扭蛋机小程序具有便捷、多样化、个性化的特点,迎合了当下消费者的线上消费习惯,又能够让扭蛋机玩家体验到新鲜有趣的扭蛋。 扭蛋机是一种热…...

Go搭建TcpSocket服务器
1.net包的强大功能 不可否认,go在网络服务开发有强大的优势。net库是一个功能强大的网络编程库,它提供了构建TCP、UDP和HTTP服务器和客户端所需的所有基础工具。 例如,搭建tcp服务器,只需要几行代码。 func main() {listener, …...

hadoop3跑第一个例子wordcount
1、创建目录 hdfs dfs -mkdir -p /user/input2、创建测试文件,并上传文件到hdfs echo 1 > 1.txt hdfs dfs -put 1.txt /user/input3、进入hadoop-3目录,并创建测试文件 cd /app/hadoop-3创建目录 mkdir wcinput cd wcinput 保存wc.input nano wc.i…...

Maven笔记(二):进阶使用
Maven笔记(二)-进阶使用 一、Maven分模块开发 分模块开发对项目的扩展性强,同时方便其他项目引入相同的功能。 将原始模块按照功能拆分成若干个子模块,方便模块间的相互调用,接口共享(类似Jar包一样之间引用、复用)…...

Apache ZooKeeper 及 Curator 使用总结
1. 下载 官网地址:Apache ZooKeeper 点击下载按钮 选择对应的版本进行下载 2. 使用 1、解压 tar -zxf apache-zookeeper-3.9.2-bin.tar.gz2、复制配置文件,有一个示例配置文件 conf/zoo_sample.cfg,此文件不能生效,需要名称为…...

深入探索:MATLAB中的硬件支持包(HSP)及其应用
在MATLAB环境中,硬件支持包(HSP)扮演着至关重要的角色,尤其是在与硬件交互和嵌入式系统开发方面。HSP提供了一套工具和库,使得MATLAB能够与特定的硬件平台进行有效通信,实现代码的生成和优化。本文将详细介…...

5.内容创作的未来:ChatGPT如何辅助写作(5/10)
引言 在信息爆炸的时代,内容创作已成为连接品牌与受众、传递信息与知识、以及塑造文化与观念的重要手段。随着数字媒体的兴起,内容创作的需求日益增长,对创作者的写作速度和质量提出了更高的要求。人工智能(AI)技术的…...

Day26_0.1基础学习MATLAB学习小技巧总结(26)——数据插值
利用空闲时间把碎片化的MATLAB知识重新系统的学习一遍,为了在这个过程中加深印象,也为了能够有所足迹,我会把自己的学习总结发在专栏中,以便学习交流。 参考书目: 1、《MATLAB基础教程 (第三版) (薛山)》 2、《MATL…...

SQL进阶技巧:火车票相邻座位预定一起可能情况查询算法 ?
目录 0 场景描述 1 数据准备 2 问题分析 2.1 分析函数法 2.2 自关联求解 3 小结...

神经网络构建原理(以MINIST为例)
神经网络构建原理(以MINIST为例) 在 MNIST 手写数字识别任务中,构建神经网络并训练模型来进行分类是经典的深度学习应用。MNIST 数据集包含 28x28 像素的手写数字图像(0-9),任务是构建一个神经网络,能够根据输入的图像…...

【ArcGIS微课1000例】0123:数据库中要素类批量转为shapefile
除了ArcGIS之外的其他GIS平台,想要打开ArcGIS数据库,可能无法直接打开,为了便于使用shp,建议直接将数据库中要素类批量转为shapefile。 文章目录 一、连接至数据库二、要素批量转shp一、连接至数据库 打开ArcMap,或者打开ArcCatalog,找到数据库连接,如下图: 数据库为个…...

【Elasticsearch系列十九】评分机制详解
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

神经网络通俗理解学习笔记(3)注意力神经网络
Tansformer 什么是注意力机制注意力的计算键值对注意力和多头注意力自注意力机制注意力池化及代码实现Transformer模型Transformer代码实现BERT 模型GPT 系列模型GPT-1模型思想GPT-2模型思想GPT-3 模型思想 T5模型ViT模型Swin Transformer模型GPT模型代码实现 什么是注意力机制…...

【C#】 EventWaitHandle的用法
EventWaitHandle 是 C# 中用于线程间同步的一个类,它提供了对共享资源的访问控制,以及线程间的同步机制。EventWaitHandle 类位于 System.Threading 命名空间下,主要用于实现互斥访问、信号量控制等场景。 创建 EventWaitHandle 创建一个 E…...

设计模式之结构型模式例题
答案:A 知识点 创建型 结构型 行为型模式 工厂方法模式 抽象工厂模式 原型模式 单例模式 构建器模式 适配器模式 桥接模式 组合模式 装饰模式 外观模式 享元模式 代理模式 模板方法模式 职责链模式 命令模式 迭代器模式 中介者模式 解释器模式 备忘录模式 观…...

camtasia2024绿色免费安装包win+mac下载含2024最新激活密钥
Hey, hey, hey!亲爱的各位小伙伴,今天我要给大家带来的是Camtasia2024中文版本,这款软件简直是视频制作爱好者的福音啊! camtasia2024绿色免费安装包winmac下载,点击链接即可保存。 先说说这个版本新加的功能吧&#…...

如何导入一个Vue并成功运行
注意1:要确保自己已经成功创建了一个Vue项目,创建项目教程在如何创建Vue项目 注意2:以下操作均在VS Code,教程在VS Code安装教程 一、Vue项目导入VS Code 1.点击文件,然后点击将文件添加到工作区 2. 选择自己的vue项…...