C++基础知识 - 异常处理机制

2023-11-09

异常处理的基本思想

  • C++的异常处理机制使得异常的引发和异常的处理不必在同一个函数中,这样底层的函数可以着重解决具体问题,而不必过多的考虑异常的处理。上层调用者可以再适当的位置设计对不同类型异常的处理。

  • 异常是专门针对抽象编程中的一系列错误进行处理的,C++中不能借助函数机制实现异常,因为栈结构的本质是先进后出,依次访问,无法进行跳跃,但错误处理的特征却是遇到错误信息就想要转到若干级之上进行重新尝试, 如图:

在这里插入图片描述

异常处理机制

  • 异常无处不在,程序随时可能误入歧途!C++ 提出了新的异常处理机制!

  • 异常是一种程序控制机制,与函数机制互补

  • 函数是一种以栈结构展开的上下函数衔接的程序控制系统,异常是另一种控制结构,它可以在出现“意外”时中断当前函数,并以某种机制(类型匹配)回馈给隔代的调用者相关的信息.

#include <stdio.h>
#include <stdlib.h>
#include <string>

using namespace std;

#define BUFSIZE 1024

//实现文件的二进制拷贝
int copyfile2(const char* dest, const char* src) {
	FILE* fp1 = NULL, * fp2 = NULL;

	//rb 只读方式打开一个二进制文件,只允许读取数据
	fopen_s(&fp1, src, "rb");

	if (fp1 == NULL) {
		throw new string("文件不存在");
	}

	//wb 以只写的方式打开或新建一个二进制文件,只允许写数据。
	fopen_s(&fp2, dest, "wb");
	if (fp2 == NULL) {
		throw - 2;
	}
	char buffer[BUFSIZE];
	int readlen, writelen;

	//如果读到数据,则大于0
	while ((readlen = fread(buffer, 1, BUFSIZE, fp1)) > 0) {
		writelen = fwrite(buffer, 1, readlen, fp2);
		if (readlen != writelen) {
			throw - 3;
		}
	}

	fclose(fp1);
	fclose(fp2);
	return 0;
}

int copyfile1(const char* dest, const char* src) {
	try{
		copyfile2(dest, src);
	} catch(float e) {		
		printf("copyfile1 - catch ...\n");
		//提示:处理不了的异常,我们可以在catch的最后一个分支,使用throw语法,继续向调用者throw。
		throw ;
	}
	return 0;
}


void main(){
	int ret = 0;

	//在需要捕捉异常的地方,将可能抛出异常的程序段嵌在try块之中
	//按正常的程序顺序执行到达try语句,然后执行try块{}内的保护段
	//如果在保护段执行期间没有引起异常,那么跟在try块后的catch子句就不执行,程序从try块后跟随的最后一个catch子句后面的语句继续执行下去
	try{//保护段
		printf("开始执行 copyfile1...\n");
		ret = copyfile1("c:/test/dest.txt", "c:/test/src.txt");
		printf("执行 copyfile1 完毕\n");
		
		//catch子句按其在try块后出现的顺序被检查,匹配的catch子句将捕获并按catch子句中的代码处理异常(或继续抛掷异常)
	}catch(int error){
		printf("出现异常啦!%d\n", error);
	}catch(string *error){
		printf("捕捉到字符串异常:%s\n", error->c_str());
		delete error;
	}catch(float error){
		printf("出现异常啦!%f\n", error);
	}catch(...){
		printf("catch ...\n");
	}

	//如果没有找到匹配,则缺省功能是调用abort终止程序。

	system("pause");
}

 
 

异常处理基本语法

异常发生第一现场,抛出异常

void  function( ) {
	//... ...
    throw 表达式;
	//... ...
}

在需要关注异常的地方,捕捉异常
try{
	//...程序
	function();
	//...程序
} catch(异常类型声明) {
	//... 异常处理代码 ...
} catch(异常类型 形参) {
	//... 异常处理代码 ...
} catch(...) { //其它异常类型
	//...
}

 

注意事项:

  • 通过 throw 操作创建一个异常对象并抛掷
  • 在需要捕捉异常的地方,将可能抛出异常的程序段嵌在 try 块之中
  • 按正常的程序顺序执行到达 try 语句,然后执行 try 块 {} 内的保护段
  • 如果在保护段执行期间没有引起异常,那么跟在 try 块后的 catch 子句就不执行,程序从 try 块后跟随的最后一个 catch 子句后面的语句继续执行下去
  • catch 子句按其在 try 块后出现的顺序被检查,匹配的 catch 子句将捕获并按 catch 子句中的代码处理异常(或继续抛掷异常)
  • 如果没有找到匹配,则缺省功能是调用 abort 终止程序。

提示:处理不了的异常,我们可以在 catch 的最后一个分支,使用 throw 语法,继续向调用者 throw 。

 
 

异常接口声明

可以在函数声明中列出可能抛出的所有异常类型,加强程序的可读性。
如:

int copyfile2(char *dest, char *src) throw (float, string *, int)

1.对于异常接口的声明,在函数声明中列出可能抛出的所有异常类型
2.如果没有包含异常接口声明,此函数可以抛出任何类型的异常
3.如果函数声明中有列出可能抛出的所有异常类型,那么抛出其它类型的异常讲可能导致程序终止
4.如果一个函数不想抛出任何异常,可以使用 throw () 声明

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

C++基础知识 - 异常处理机制 的相关文章

  • 将 Stream 反序列化为 List 或任何其他类型

    尝试将流反序列化为List
  • 获取 std::variant 当前持有的 typeid(如 boost::variant type())

    我已经从 boost variant 迁移到 std variant 但遇到了障碍 我在 boost type 中使用了一个很好的函数 它可以让你获取当前持有的 typeid 看https www boost org doc libs 1
  • 如何在编译C代码时禁用警告?

    我正在使用 32 位 Fedora 14 系统 我正在使用编译我的源代码gcc 有谁知道如何在编译c代码时禁用警告 EDIT 是的 我知道 最好的办法是修复这些警告以避免任何未定义 未知的行为 但目前在这里 我第一次编写了巨大的代码 并且在
  • Qt 计算和比较密码哈希

    目前正在 Qt 中为测验程序构建面向 Web 的身份验证服务 据我了解 在数据库中存储用户密码时 必须对其进行隐藏 以防落入坏人之手 流行的方法似乎是添加的过程Salt https en wikipedia org wiki Salt cr
  • 是否有像 gccxml 这样的用于生成包装器的 C 标头解析器工具?

    我需要为一种新的编程语言编写一些 C 标头包装器 并且想要类似 gccxml 的东西 但不完全依赖 gcc 以及它在 Windows 系统上带来的问题 只需要读C而不是C 只要有完整的文档记录 任何格式的输出都可以 Linux Solari
  • 如何使用 wpf webbrowser 将数据发布到 Web 服务器

    我想从数据库获取数据并使用它来让用户登录到网站 我有一个包含 Web 浏览器控件的 wpf 页面 我有这样的代码 用于将用户登录到用 php 编写的网站
  • 在 MATLAB 中创建共享库

    一位研究人员在 MATLAB 中创建了一个小型仿真 我们希望其他人也能使用它 我的计划是进行模拟 清理一些东西并将其变成一组函数 然后我打算将其编译成C库并使用SWIG https en wikipedia org wiki SWIG创建一
  • 指向字节数组的指针

    由于 Misra C 的要求 我的一位同事想要使用指针声明 但我遇到了一些问题 Misra 安全关键指南 不会让我们纯粹的程序员使用指针 但会让我们对数组字节进行操作 他打算获取一个指向字节数组的指针 因此我们不会在堆栈上传递实际的数组 T
  • 操纵 setter 以避免 null

    通常我们有 public string code get set 如果最终有人将代码设置为 null 我需要避免空引用异常 我尝试这个想法 有什么帮助吗 public string code get set if code null cod
  • 在简单注入器中注册具有多个构造函数和字符串依赖项的类型

    我正在尝试弄清楚如何使用 Simple Injector 我在项目中使用了它 注册简单服务及其组件没有任何问题 但是 当组件具有两个以上实现接口的构造函数时 我想使用依赖注入器 public DAL IDAL private Logger
  • 如何用 C 语言练习 Unix 编程?

    经过五年的专业 Java 以及较小程度上的 Python 编程并慢慢感觉到我的计算机科学教育逐渐消失 我决定要拓宽我的视野 对世界的一般用处 并做一些 对我来说 感觉更重要的事情就像我真的对机器有影响一样 我选择学习 C 和 Unix 编程
  • 允许使用什么类型的内容作为 C 预处理器宏的参数?

    老实说 我很了解 C 编程语言的语法 但对 C 预处理器的语法几乎一无所知 尽管我有时在编程实践中使用它 所以问题来了 假设我们有一个简单的宏 它扩展为空 define macro param 可以放入宏调用构造中的语法有哪些限制 调用宏时
  • 将非算术类型作为参数传递给 cmath 函数是否有效?

    给定以下用户定义类型S具有转换功能double struct S operator double return 1 0 以及以下调用cmath http en cppreference com w cpp header cmath使用类型的
  • 如何将对象转换为传递给函数的类型?

    这不会编译 但我想做的只是将对象转换为传递给函数的 t public void My Func Object input Type t t object ab TypeDescriptor GetConverter t ConvertFro
  • 如何获取 QIcon 的文件/资源​​路径

    假设我做了这样的事情 QIcon myIcon resources icon ico 我稍后如何确定该图标的路径 例如 QString path myIcon getPath 问题是 没有getPath 会员 我找不到类似的东西 但肯定有办
  • 在 C++ 和 Windows 中使用 XmlRpc

    我需要在 Windows 平台上使用 C 中的 XmlRpc 尽管我的朋友向我保证 XmlRpc 是一种 广泛可用的标准技术 但可用的库并不多 事实上 我只找到一个库可以在 Windows 上执行此操作 另外一个库声称 您必须做很多工作才能
  • 使用 Chrome 和 Selenium 设置 LocalStorage

    我正在尝试使用 OpenQA Selenium 和 Chrome 设置本地存储键和值 我认为这相当微不足道 但我似乎无法让它发挥作用 我对 C 很陌生 所以我可能错过了一些东西 无论如何 我有这个功能 public static void
  • 从有符号字符转换为无符号字符然后再转换回来?

    我正在使用 JNI 并有一个 jbyte 类型的数组 其中 jbyte 表示为有符号字符 即范围从 128 到 127 jbyte 表示图像像素 对于图像处理 我们通常希望像素分量的范围为0到255 因此 我想将jbyte值转换为0到255
  • c# 模拟 IFormFile CopyToAsync() 方法

    我正在对一个异步函数进行单元测试 该函数将 IFormFile 列表转换为我自己的任意数据库文件类列表 将文件数据转换为字节数组的方法是 internal async Task
  • FindAsync 很慢,但是延迟加载很快

    在我的代码中 我曾经使用加载相关实体await FindAsync 希望我能更好地遵守 C 异步指南 var activeTemplate await exec DbContext FormTemplates FindAsync exec

随机推荐

  • 单链表按照指定顺序插入节点(思路分析) [数据结构][Java]

    单链表按照特定顺序插入节点 思路分析 这里我们要实现在自定义的英雄链表中添加英雄时 根据排名将英雄插入到指定位置 如果有链表中已经有这个排名了 那么就添加失败 并且给出提示 思路分析 首先找到待添加结点位置的前一个位置 涉及到遍历 所以是通
  • python中导入TXT时,使用split()分割文本时,出现错误ValueError: not enough values to unpack (expected 2, got 1)

    Python中使用str split 时 一般都会有两个参数 比如 role words str split 1 注意split的 它必须和str中的冒号 str中必须有冒号 否则就会报错 都是同一种冒号 要么是英文半角 要么是中文冒号 如
  • easyx图形库-----贴图技巧之透明贴图与位运算(与运算、或运算、异或运算)

    目录 位运算 1 与运算 2 或运算 3 异或运算 2 图形库颜色位运算与透明贴图实现 相关操作码 透明贴图的实现 我们都知道电脑的系统处理方式都是以二进制去处理的 每一个数据的背后都是二进制数字0跟1表示 那么这一期我就来介绍怎么去利用二
  • MFC 菜单 menu

    在网上看了怎样制作一个菜单 往往说的内容很多 但自己还是没看懂 今天看了一个公司前人写的一个程序 原来这么简单 给大家分享一下 就用一个基于对话框的MFC程序为例吧 首先 新建一个菜单 点击resource Dialog 右击insert
  • 视觉SLAM实践入门——(20)视觉里程计之直接法

    多层直接法的过程 1 读图 随机取点并计算深度 2 创建图像金字塔 相机内参也需要缩放 并计算对应点的像素坐标 3 应用单层直接法 使用G N L M等方法 或者使用g2o ceres库 进行优化 源码中有一些地方会引起段错误 修改方法见下
  • 嵌入式单片机基础篇(三十一)之Stm32F103与WiFi模块ESP8266 Station模式控制LED灯程序

    Stm32F103与WiFi模块ESP8266 Station模式控制LED灯程序 include stm32f10x h include string h include stdio h unsigned char UARTbuff 10
  • 富文本编辑器wangEditor的使用(即学即用)

    介绍 wangEditor 是一款基于JavaScript和CSS开发的Web富文本编辑器 其具有轻量级 简洁 易用的特点 当然 市面上有许多别的富文本编辑器 各有特点 本文专注于介绍wangEditor这一款富文本编辑器 首先明确一点 什
  • (三)目标检测之 R-CNN系列

    目标检测之 R CNN系列 前言 R CNN系列 一 R CNN https arxiv org abs 1311 2524 二 Fast R CNN https arxiv org abs 1504 08083 三 Faster R CN
  • 调用关卡蓝图上的接口函数

    本片博客实现的是不同蓝图之间用接口实现通信 下面用附上新建蓝图接口的大体步骤和实现的蓝图逻辑 新建蓝图接口 在蓝图接口里面新建函数 在关卡蓝图里面实现函数 如下图所示 然后在控件蓝图里面调用该接口 具体实现如下图
  • 加快android编译速度

    一 修改运行内存 进入项目 菜单栏 help Edit Custom VM Option Paste Image png 添加或修改为 Xms2048m Xmx2048m XX MaxPermSize 2048m XX ReservedCo
  • 数据可视化实例阅读分析

    一 任务要求 从教材或网络上找一个可视化实例 简要分析该实例 要求 1 根据可视化图反推出该图所依据的数据表并绘出 指出表中各列数据的属性 即类型 N O Q型 5分 2 找出可视化图形中的所有视觉变量 3分 3 分析从数据属性到视觉变量的
  • 使用haproxy 配置rabbitmq消息队列主从

    1 创建haproxy的配置文件 sudo vi etc haproxy ha rabbit conf 2 配置前向业务访问frontend 前置代理 bind 0 0 0 0 5672 绑定0 0 0 0的5672端口 mode tcp
  • 博物馆(展览馆)RFID信息化建设管理方案

    项目概述 基于博物馆 展览馆 RFID信息化建设管理方案 博物馆是征集 典藏 陈列和研究代表自然和人类文化遗产的实物的场所 并对那些有科学性 历史性或艺术价值的物品进行分类 为公众提供知识 教育和欣赏的文化教育机构 建筑物 地点或社会公共机
  • openresty ngx_lua定时任务

    openresty ngx lua定时任务 ngx timer every https github com openresty lua nginx module ngxtimerevery ngx timer at https githu
  • No implementation found for void java接口不能跳转到实现类

    No implementation found for void 前两天idea还是好的 现在就是不能跳转到impl实现类 总是提示no implementation found for void 后来通过百度发现 其实是idea的缓存在作
  • 【知识学习】马氏距离 Mahalanobis Distance

    目录 1 协方差的意义 2 马氏距离 2 1 概述 2 2 公式 2 3 实际意义 2 4 局限性 2 4 1 协方差矩阵必须满秩 不平衡数据少数类一般都不是 2 4 2 不能处理非线性流形 manifold 的问题 线性流形和非线性流形
  • JSON.parseArray报错

    JSON parseArray报错 com alibaba fastjson JSONException syntax error expect actual error pos 1 fastjson version 1 2 47 解决方案
  • 在JavaScript中确认字符串结尾的两种方法

    In this article I ll explain how to solve freeCodeCamp s Confirm the Ending challenge This involves checking whether a s
  • 有趣的xss靶场

    最近发现一个在线xss靶场 挺有趣的 靶场只有12关卡 上面还写了服务区原代码 对于想入门xss的小伙伴可以试着玩一玩 结果只要实现弹窗结果为1即可 链接在这里 https xss haozi me 0x00 server code fun
  • C++基础知识 - 异常处理机制

    异常处理的基本思想 C 的异常处理机制使得异常的引发和异常的处理不必在同一个函数中 这样底层的函数可以着重解决具体问题 而不必过多的考虑异常的处理 上层调用者可以再适当的位置设计对不同类型异常的处理 异常是专门针对抽象编程中的一系列错误进行