C++ 异常处理 重新throw变量时的事件

news2025/9/24 22:25:57

直接说结论:throw的表达式创建出来的变量会被拷贝下来【通过拷贝构造函数,后面会证实这一点,且是放在堆里的】,然后沿着调用路径去搜索最近匹配异常的catch语句,在沿途,传递给catch语句的是堆中的异常变量的拷贝;

下面来证明一件事:

1:异常的传递是靠拷贝进行的。

看代码:

#include<iostream>
#include<memory>
using namespace std;

class m_exception :public exception {
public:
	m_exception(const char* message) 
	:exception(message){
		cout << this << endl;
	}
	void printAddress() {
		cout << this << endl;
	}
	~m_exception() {}
};

void f() {
	m_exception e= m_exception("e");
	throw e;
}

void g() {
	try {
		f();
	}
	catch (m_exception e) {
		e.printAddress();
		throw;
	}
}

int main() {
	try {
		g();
	}
	catch (m_exception e) {
		e.printAddress();
	}
}

运行结果:

 可以看见,每个catch语句中的变量地址都是不同的,所以这能说明传递异常的方式是拷贝。

如果我们是将拷贝构造函数delete掉的话:

m_exception(const m_exception e) = delete;

编译器就会报错:

 这也能说明这是变量是靠拷贝构造函数传递的;

下面来证明两件事

1:最开始throw异常的的表达式会将异常拷贝到堆里最后由系统回收;

2:每次拷贝的不是下一层传递来的异常,而是存储在堆中的原始异常;

先来证明1:

#include<iostream>
#include<memory>
using namespace std;

class m_exception :public exception {
public:
	int x = 100;
	m_exception(const char* message) 
	:exception(message){
		cout << this << endl;
	}
	void printAddress() {
		cout << this << endl;
	}
	~m_exception() {}
};

void f() {
	m_exception e= m_exception("e");
	throw e;
}

void g() {
	try {
		f();
	}
	catch (m_exception e) {
		e.x = 1000;
		cout << e.x << endl;
		e.printAddress();
		throw;
	}
}

int main() {
	try {
		g();
	}
	catch (m_exception e) {
		cout << e.x << endl;
		e.printAddress();
	}
}

运行结果:

可以看到,虽然我们在g中修改了x,但是并没有影响到main中的异常,所以上一级的环境并不是拷贝下一级环境的异常;

当我们将catch的参数改为引用时:

void g() {
	try {
		f();
	}
	catch (m_exception& e) {
		e.x = 1000;
		cout << e.x << endl;
		e.printAddress();
		throw;
	}
}

int main() {
	try {
		g();
	}
	catch (m_exception& e) {
		cout << e.x << endl;
		e.printAddress();
	}
}

运行结果:

可以看到,两个异常的地址相同,且g中的修改能影响到main;

综上所述,我们完全有理由肯定,每一层的catch语句都是捕获属于其本身的原异常的拷贝副本;

我们知道,c++的存储空间可以分为栈空间和堆空间,当我们的能在不同函数之间安全传递的变量只能是堆空间上的变量,所以我们也有充分的理由信息,这个变量是在堆上的;

证明完毕;

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

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

相关文章

2022年数维杯国际大学生数学建模挑战赛D题三重拉尼娜事件下极端气候灾害损失评估与应对策略研究解题过程

2022年数维杯国际大学生数学建模挑战赛 D题 三重拉尼娜事件下极端气候灾害损失评估与应对策略研究 原题再现&#xff1a; 2022年7月至8月&#xff0c;中国南方许多城市经历了多天的炎热天气&#xff0c;而北方部分地区也出现了大面积强降水。此外&#xff0c;许多欧洲国家也经…

GEE开发之Modis_NDVI数据分析获取大总结

GEE开发之Modis_NDVI数据分析获取大总结0. 之前的博客链接1. MYD13Q1(250米/16天)2. MOD09GA_006_NDVI(500米/1天)3. MOD13Q1(250米/16天)4. MOD13A1(500米/16天)5. MOD13A2(1000米/16天)6. 日数据下载(以MYD13Q1为例子)7. 月数据下载(以MYD13Q1为例子)7.1 代码一7.2 代码二&am…

博途1200PLC轴控功能块(脉冲轴)

1200选择晶体管输出的型号,本体支持脉冲发送,利用工艺对象可以组态脉冲轴。利用1200和1500PN总线可以进行总线伺服的控制,具体请参看下面的博客: 博途1200/1500PLC V90 PN通信控制 (FB284功能块)_RXXW_Dor的博客-CSDN博客_fb284功能块先简单说下如何获取FB284,一般有2种方…

redirs非关系型数据库使用

非关系型数据库是将不经常使用的数据保存到redis缓存中&#xff0c;当前端访问redis缓存数据&#xff0c;如果没有查到该数据&#xff0c;则从数据库中查询&#xff0c;并将数据缓存到redis里。 数据结构介绍&#xff1a; redis的存储主要是key,value的数据格式&#xff0c;其…

Node.js 是如何做 GC (垃圾回收)的?

大家好&#xff0c;我是前端西瓜哥。今天我们来研究一下 Node.js 是如何做 GC 的。 GC&#xff0c;Garbage Collection&#xff0c;垃圾回收。在编程中&#xff0c;一般指的是内存自动回收机制&#xff0c;会定时将不需要用到的数据进行清除。 Node.js 底层使用了 V8 引擎。V…

Android入门第31天-Android里的ViewFlipper翻转视图的使用

介绍 本篇给大家带了的是ViewFlipper&#xff0c;它是Android自带的一个多页面管理控件&#xff0c;且可以自动播放&#xff01; 和ViewPager不同&#xff0c;ViewPager是一页页的&#xff0c;而ViewFlipper则是一层层的&#xff0c;和ViewPager一样&#xff0c;很多时候&…

Vivado在Linux下的安装与运行

一. Vivado安装步骤 下载解压安装包后&#xff0c;并进入安装包路径运行终端 cd Downloads/Xilinx_Vivado_SDK_2017.4运行 sudo apt install libncurses5 安装ncurses库 sudo apt install libncurses5 运行 sudo chmod x setup 添加可执行权限 sudo chmod x setup运行 sudo .…

PHP反序列化漏洞解析

序列化 所谓序列化就是将原数据对象转换为具有一定格式的数据 举一个最简单的例子&#xff0c;在C中&#xff0c;若要开发一个数据库&#xff0c;那么一定涉及到数据的存储&#xff0c;要将内存中的数据持久化的保存在磁盘中&#xff0c;这就要对数据的存储格式进行优化&…

[附源码]java毕业设计企业信息网站

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

网关及其分类

1. 介绍 大家都知道&#xff0c;从一个房间走到另一个房间&#xff0c;必然要经过一扇门。同样&#xff0c;从一个网络向另一个网络发送信息&#xff0c;也必须经过一道“关口”&#xff0c;这道关口就是网关。顾名思义&#xff0c;网关(Gateway)就是一个网络连接到另一个网络的…

深度探究多线程的效率以及多线程的使用建议

随着时代发展&#xff0c;电脑的核心数慢慢增多&#xff0c;在开发程序的过程中&#xff0c;是否选择使用多线程这是个比较大的问题&#xff0c;下面我通过一个程序去深入理解多线程对程序速度的影响到底有多大 计算亿级别个数的累加和&#xff1a; 单线程模型运行程序&#…

SNMP(二)

♥️作者&#xff1a;小刘在C站 ♥️每天分享云计算网络运维课堂笔记&#xff0c;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的&#xff0c;绽放。 目录 一.SNMP是什么 二.SolarWinds 网管软件使用 步骤1 步骤2 步骤3 步骤4 三.SNMP命令…

使用go pprof进行golang程序内存分析

引言 日常项目&#xff0c;有时会出现oom的情况&#xff0c;这时候我们光依靠code review进行问题定位是很困难的。这里我们需要一个排查工具&#xff0c;来定位是哪里的代码导致内存溢出的&#xff0c;这个工具就是pprof前提 如果是非http(s)服务类的&#xff0c;需要在代码…

基于PHP+MySQL的宠物领养救助社交网站

当前很多的宠物被抛弃和虐杀,它们没有选择权,我们强制性的把狗带进人类的生活中,然后又无情的抛弃,让它们无家可归,变成流浪狗,它们做错了什么&#xff1f;流浪动物被主人遗弃之后居无定所,时刻面对着严寒、酷暑、生病、死亡,饥饿、等一系列威胁它们生命的存在为了能够让这些。…

BlenderGIS插件 城市建筑3D模型自动生成 教程

目录 一、下载Blender和BlenderGIS 二、解决 No imaging library...报错 三、生成城市3D模型 四、导出模型 本文所需文件可在如下链接下载&#xff0c;或者直接按照博文下载步骤下载 https://download.csdn.net/download/ChaoChao66666/87071901?spm1001.2014.3001.550…

Node的Web编程

一、node的事件处理 1、node采用的事件驱动模式来进行事件处理的&#xff1a;只有当事件被触发时才执行相关程序 2、node是单线程运行的&#xff1a;采用事件轮询方式&#xff0c;不断的查询事件队列中的消息&#xff0c;然后根据消息执行对应的回调函数 3、node事件机制中的…

ASEMI代理艾赛斯DSP25-12A,整流二极管DSP25-12A

编辑-Z 艾赛斯整流二极管DSP25-12A参数&#xff1a; 型号&#xff1a;DSP25-12A 最大重复反向阻断电压&#xff08;VRRM&#xff09;&#xff1a;1200V 反向电流、漏极电流&#xff08;IR&#xff09;&#xff1a;40uA 正向电压降&#xff08;VF&#xff09;&#xff1a;1…

this用法总结

文章目录1.常规下this的指向1.1 全局环境中的this1.2 上下文对象调用中的this1.3 this指向绑定事件的元素1.4 箭头函数的this指向2. 改变this指向2.1 call - Function.prototype.call( )2.1.1 call的第一个参数2.1.2 call接受多个参数2.1.3 调用对象的原生方法2.2 apply - Func…

LFMCW雷达测速基础- 多普勒频移和2DFFT

LFMCW雷达测速基础1 基本测速原理——多普勒频移1.0 写在前面1.1 多普勒效应1.2 多普勒频移疑问2 LFMCW雷达测速原理2.1 Doppler Shift 到底是调频还是调相2.2 为什么是二维FFT1 基本测速原理——多普勒频移 1.0 写在前面 振动/波在空间中传播有三个关键变量&#xff0c;分别…

iNFTnews|Web3正在重新定义粉丝的意义

数字身份正在发展&#xff0c;粉丝圈本身也在发展。Web3技术使粉丝们能够以一种更加人际化的方式与同好、媒体、内容创作者甚至他们崇拜的名人进行互动&#xff0c;粉丝和创作者都可以获得更人性化的体验。另外&#xff0c;一些激励措施还有望从根本上改变我们对名人概念本身的…