用C++ 而不是 用c (4)使用异常和返回值

Windows 结构化异常与 C / C++异常的一些事 一直以来对“异常”以及相关的知识很模糊,这次做个整理,回答几个基本问题以帮助对“异常”的理解: C语言的异常C语言版的try/catch: setjmp, longjmp C++的异常(try/catch)Windows 结构化异常,以及与C++标准异常的联系(__try/__except与try/catch)在Windows API 与标准C++代码混用的项目中,如何较好的捕捉所有异常? 阅读详情

使用异常和返回值
1.使用返回值处理错误需要程序员严格的编程作风,程序员不论是否有这种习惯,这都是非常不希望的。
2.正确的异常处理是C++中的一个常识。异常通过发出错误信号,可以让程序代码和错误处理代码分开,而且不会让程序忽略错误。
3.必须了解使用了哪种错误处理方法,返回值还是抛出异常。如果不知道,那么你的程序肯定有问题。
4.异常是基于每个线程而提出并处理的;异常不能被线程忽略,必须被处理;未处理的异常会使进程结束,而不仅仅是线程结束;异常处理在释放栈时会释放所有的栈对象,因此避免了资源的漏洞;异常处理需要大量的额外操作,使得它并不适于经常运行的代码。详细的说,catch块有一些开销(overhead),但是try块有很少的开销;因此只有在抛出异常的时候才会有很多的异常操作开销;你可以抛出任何类型的异常对象,但不包括整数。
5.返回值可以指示正常和不正常的函数运行,但不能阻止线程的继续运行;返回值很容易被忽略;返回值在典型的情况下是一个整数,通常映射符合于一个预定义的值;返回值能高效的传递和接收;
6.所有的非错误的状态信息都应该使用返回值
7.返回值用于大多数情况下可以随意忽略而不会出现问题的错误
8.在循环中的错误处理必须快速,因为异常的额外开销,所以为了得到更好的性能,使用返回值是一个更好的选择。在这种情况下,如果你真要使用异常,可以创建一个函数来将返回值转化未异常。
9.使用于中间语言模块中的错误。
10.使用Windows API的错误处理机制。用SetLastError设置错误代码,通过GetLastError检测这个错误代码。
11.从C++异常处理的观点看,故障应该被认为是错误。
12.你必须使用/Eha调试器选项来扑获使用C++异常操作机制的操作系统异常。
14.Windows结构异常处理:使用_try,_except,_finally,_leave关键字和RaiseException API函数;由Windows支持,不适于其他操作系统;不处理C++对象的解析;作为硬件异常或操作系统异常的结果抛出,也可作为RaiseException函数结果被抛出。
15.C++异常处理:使用try,throw和catch等关键字;仅被C++语言支持;处理C++对象的解析;可以抛出任何类型的C++对象。异常对象可以从标准的异常基本类派生,也可以从任何类派生,或者它们也可以是内置的类型;作为throw语句的结果被抛出。
16.Visual C++ 使用结构异常处理机制实现C++异常。
17.结构异常处理不能处理对象的解析,因此你应该在C++程序中一直使用C++异常。然而,因为C++异常不能处理硬件和操作系统异常,你的程序需要将结构异常转化为C++异常。
18.为了正确处理硬件和操作系统异常,你可以创建自己的异常类并使用_set_se_translator函数安装一个结构异常向C++异常的转化器。
19.不要扑获那些不能恢复所产生问题的转化后的结构异常。
20.在很少抛出异常的情况下使用异常的代价并不是很大,而且这样做确实可以提高性能。
21.异常策略中最重要的一部分实际上就是有一个策略。不要在事后弥补。
22.异常扑获规则:扑获处理器按顺序提供;如果扑获处理器扑获了同一类型或指向同一类型抛出对象的指针,则应扑获异常。如果扑获处理器扑获了一个公共基类或者指向一个公共基类抛出对象的指针,则应扑获异常;一个省略扑获处理器扑获任何类型的异常,因此它总是放在最后。
23.定义一个异常基类来处理程序代码抛出的异常。
 class CProgramException : public exception {
 public:
 CProgramException (const _exString &_what_arg) :
  exception(_what_arg) {}
};
使用CProgramException类使得异常处理更加简单,因为可以通过处理这种基类扑获所有的程序中的异常。如果需要的话,也可以使用额外的成员数据全面描述特定的问题。
24.使用auto_ptr或者一个类似的指针类通过限制局部变量的动态分配来自动释放资源:
void LeakFreeFunction (int arg) {
 auto_ptr<CMyObject> pObject(new CMyObject(arg));
 ... // do something that throws an exception
 // can still call member functions as normal
 pObject->MemberFunction();
 // no need to delete pObject
}
注意:auto_ptr仅在使用delete释放资源时使用。
25.使用异常处理更简单,更可靠,更有效,可以创建更健壮的代码。然而,你应该只在意外的情况下使用异常处理。如果你认为一个指针应该时空值,这种条件下就直接在代码中检查这个值,而不要使用异常。
26.非MFC的C++异常应该通过引用来扑获。使用引用扑获异常不需要删除异常对象(因为使用引用扑获的异常会在栈中传送),而且它保留了多态性(因此你扑获的异常对象正是你抛出的异常对象)。使用指针扑获异常需要你删除对象,而使用值扑获对象会导致对象的“分片”(slicing),也就是说,将派生的异常对象转化为扑获的数据类型。
27.MFC异常应该通过指针来扑获。因为它们通常从堆中分配,当你处理完异常之后,你需要调用Delete成员函数:
...
catch (CFileException *e) {
 // handle file exception
 ...
 e->Delete(); // required to prevent a memory leak
}
因此,你不可以使用省略扑获处理器扑获MFC异常,因为者会导致一个内存泄漏。你必须使用Delete成员函数删除MFC异常,而不要用delete操作符,因为一些MFC异常作为静态对象创建。
28.一旦扑获了异常,你可以通过执行下列典型动作的一些组合来处理它:
 (1) 什么也不要做。
 (2) 修改这个问题并重试代码。
 (3) 修改这个问题但不要重试代码。
 (4) 如果用户需要的话,向用户显示错误信息。
 (5) 如果出现的问题不是程序错误的话,输出一个诊断的跟踪消息。
 (6) 如果出现的问题是程序错误,输出一个断言。
 (7) 在日志文件中记录这个问题。
 (8) 如果异常是不可恢复的,停止进程的运行。
 (9) 整理已分配的资源。
 (10) 重新抛出这个异常,使得高级函数也能处理这个异常,特别是在当前函数不能完全解决的情况下。你可以重新抛出同一个异常对象,或抛出一个新的异常对象。
29.和/EHa相对的是同步异常(/EHs),而不是/GX。/GX实际上是/EHsc的简化形式。/GX表示编译器应该假设extern "C" 的函数不抛出C++异常,而/EHs则抛出。
30.为用户和调用环境记录异常。通常,异常对象类型用于向调用环境通知出现的问题,而问题的描述字符串用于向用户通知。
31.Visual C++的默认情况下,new和malloc对于错误不会抛出异常,但你可以通过使用_set_new_handler安装一个处理器,让new针对错误抛出异常。你也可以让malloc通过调用_set_new_mode使用同一处理器。
#include <new.h>

class bad_alloc : public exception {
public:
 bad_alloc(const __exString& what_arg) : exception (what_arg) {}
};

int NewHandler (size_t size) {
 throw bad_alloc("Operator new couldn't allocate memory");
 return 0;
}

int APIENTRY WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,int nCmdShow) {
 _set_new_handler(NewHandler);
 _set_new_mode(1);   // use NewHandler for malloc as well
 ...
}

32.如果已存在的代码中没有设定new返回空值,那么你应该始终让new出错时抛出一个异常。
33.浮点数和整数不一样,在默认情况下它被零除不会出现异常,但是会出现一个非常奇怪的值"1.#INFO" (它表示这个值并不是一个数字)。要让检测浮点数问题更简单一些,你应该用如下的代码让浮点数错误抛出异常。
#include <float.h>
int cw=controlfp(0,0);
cw &= ~(EM_OVERFLOW | EM_UNDERFLOW | EM_INEXACT | EM_ZERODIVIDE | EM_DENORMAL | EM_INVALID);
_controlfp(cw, MCW_EM);
浮点数异常处理器必须调用_clearfp作为它的第一条指令来清空浮点数异常。

Gamit10.71添加新的天线类型 添加新的天线类型需要涉及到四个文件:antmod.dat,rcvant.dat,guess_rcvant.dat,hi.dat。 注意:格式要一致!!! 举例说明,我要添加一个JCA229的天线(带JCAD天线罩),对应接收机使用的是南方的South Net-S9。 阅读详情

相关推荐

STM32F103ZET6【标准库函数开发】------04五个串口配置实战:从零到一构建多串口通信系统

本文详细介绍了STM32F103ZET6标准库函数开发中五个串口(USART/UART)的配置实战,从硬件引脚识别、时钟树配置到多串口系统整合技巧。通过具体代码示例和调试经验,帮助开发者快速构建稳定的多串口通信系统,适用于工业控制、物联网网关等应用场景。

weixin_29188997的博客 344

C++之异常处理

为什么引入异常 在C语言中错误的处理,通常采用返回值的方式或是使用全局变量的方式。这就存在两个问题,一是如果返回值正是我们需要的数据,这就导致了返回数据同出错数据容错差不高。 二是全局变量,在多线程中易引发竞争,而且,当错误发生时,上级函数要出错处理,层层上报,造成过多的出错处理代码,且传递的效率低下。 因此C++引入了面向对象级别的异常处理机制。 在C++中异常的处理和具体逻辑的处理不比在同一个函数中,这样就可以做到底层逻辑专注于功能的实现,具体错误处理交由上层业务逻辑去处理。 异常如何使用? 使用关键字

u012944685的专栏 3423

从Protocol到硬件控制:揭秘高通UEFI中ABL与XBL的协作机制

本文深入解析了高通UEFI架构中ABL与XBL的协作机制,重点探讨了Protocol通信在硬件控制中的关键作用。通过对比传统GPIO控制方式,揭示了Protocol架构在安全性、可维护性和灵活性方面的优势,并提供了关机充电场景的实战案例分析及调试技巧。

weixin_29185199的博客 431

C++中处理异常的方法及代码演示

异常处理就是处理程序中的错误。所谓错误是指在程序运行过程中发生的一些异常事件。

weixin_58796863的博客 690

基于FPGA的IIR数字滤波器设计

一种是在直接法的基础上,采用预见的算法,目的是提高系统的吞吐量(指对于网络、端口设备或者其他的设施,单位时间内成功传输数据的数量,比特、字节和分组是吞吐量常用的单位),带有预见算法编程实现的IIR数字滤波器有更多的优点,例如:数据传送速度快,效率高等等;设计模拟滤波器时,它的电路一般都很复杂,而且分析起来也很麻烦,电路的复杂性就决定了使用的器件必定很多,很复杂,就这一方面看来,数字滤波器的设计要更加简单灵活,并且模拟电路不容易改变系统的参数,它的性能还很容易受到温度环境的影响,使得噪声很大。

毕业设计区博客 2121

第十一届全国大学生GIS应用技能大赛——广西区域发展布局示意图

我们需要制作一幅广西区域发展布局示意图,最终成图参考“数据”文件夹中的广西区域发展布局示意图.png。地图使用的投影坐标系是 Asia_North_Albers_Equal_Area_Conic,其中地理坐标系是China_Geodetic_Coordinate_System_2000,中央经线东经 105°,标准纬线是北纬 25°和北纬 47°,出图比例尺 1:4,780,000。

@HNUSTer的博客 7799

[C++番外] 第三十三节 抛异常

异常总体而言,利大于弊,所以工程中我们还是鼓励使用异常的。

2301_80017277的博客 1401

AutoSAR MemMap模块详解及使用注意事项

在本文中,我们将深入探讨MemMap模块的实例解析,并介绍在使用该模块时需要注意的一些事项。在上述代码中,我们使用了MEMMAP_START_SEC_VAR_32BIT和MEMMAP_START_SEC_CODE来定义MemMap区域的起始位置,使用MEMMAP_STOP_SEC_VAR_32BIT和MEMMAP_STOP_SEC_CODE来定义MemMap区域的结束位置。1.合理划分MemMap区域:根据实际需求,合理划分MemMap区域,将不同类型的变量放置在不同的区域中,以便于管理和访问。

weixin_50547796的博客 2533

C++ throw

我们知道C++ 异常处理的流程,具体为: 抛出(Throw)--> 检测(Try) --> 捕获(Catch) 异常必须显式地抛出,才能被检测和捕获到;如果没有显式的抛出,即使有异常也检测不到。 在 C++ 中,我们使用 throw 关键字来显式地抛出异常,它的用法为: throw exceptionData; exceptionData 是“异常数据”的意思,它可以包含任意的信息...

weixin_45743799的博客 9096

“反激电源”是AC/DC隔离电源还是DC/DC隔离电源?

所以在一些场景,我们的输入电压是一个DC,但是我们仍然需要隔离电源的需求,我们就会只采用图9.2的右半部分。在这个场景下“反激电源”是DC/DC。所以此AC/DC的本质是将AC变成高压的DC之后,用带隔离变压器的反激式开关电源产生一个隔离的、稳定的直流电压。一般在讲述各种电源的拓扑的文章和书籍都是在讲述AC/DC的电源拓扑分类的时候,讲述Flyback。反激式开关电源是指使用反激高频变压器隔离输入输出回路的开关电源,反激式隔离变压器开关电源重点表述的是开关电源包含变压器的拓扑结构。

qq_43416206的博客 1295

学Simulink——基于故障诊断与容错控制的场景实例:并网逆变器在短路故障下的动态响应及恢复策略

本文详细介绍了使用Simulink进行并网逆变器短路故障模拟与保护策略设计的方法。通过构建高精度逆变器模型,模拟IGBT击穿和桥臂直通故障,分析动态响应特性。重点设计了基于Stateflow的微秒级快速保护逻辑,包括过流检测、PWM闭锁和故障报警。同时提出完整的恢复策略流程,涵盖放电、去磁、自检和软启动等关键步骤。仿真结果表明,该方法能在200μs内有效限制短路电流,保护器件安全,并实现系统可靠恢复。文章还探讨了硬件保护协同、多级保护和预测保护等高级策略,为新能源系统的安全运行提供了重要参考。

amy_mhd的博客 143

C++异常处理解析3: 错误处理(返回值, 错误标志变量, 异常)各有千秋

C++异常处理解析3: 错误处理(返回值, 错误标志变量, 异常)各有千秋 发表于 2013 年 9 月 29 日 作者 sigmainfy   浏览次数:0 次 — 暂无评论 ↓ 前言: 程序设计里面至关重要的一块就是错误处理, C++异常处理是一种面向对象的机制, 期望将错误处理和错误检测分离. 这里我们结合其他两种错误处理方式(返回值, 错误标志变量)来分析

Stroller 5442

【YOLOv11多模态融合改进】(可见光+红外)涉及像素级融合、特征级融合(中期、中后期、后期)、决策级融合的完整配置步骤以及二次改进方案

在网络输入阶段将多模态数据直接合并,形成统一的特征表示。

Limiiiing的博客 1968

用C++而不是用c(4)使用异常和返回值

用C++而不是用c(4)使用异常和返回值原文:用C++而不是用c(4)使用异常和返回值  

^_^纯一狼^o^ 1657

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

[cpp进阶]C++异常

在实际使用中,我们会自定义异常体系进行规范的异常管理,因为一个项目中如果大家随意抛异常,那么外层的调用者没有办法识别异常是从哪一个业务层抛出的,所以实际中都会定义一套继承的规范体系。

weixin_53027918的博客 2967

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C++『异常』

异常处理在软件开发中扮演着关键的角色,它为程序员提供了一种有力的手段来处理和响应程序执行过程中可能出现的错误。本文将深入探讨异常的基本概念、异常处理方式、异常的使用技巧和异常体系的设计,以帮助开发者更好地理解和应用异常处理机制

北 海的博客 2425

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

[cpp] 异常

[cpp] 异常 详解

BinaryWiker的博客 1576

C++11:异常的捕获和处理

异常是一种处理错误的方式,当一个函数发现自己无法处理的错误时就可以抛出异常,让函数的直接或间接的调用者处理这个错误。

weixin_51142926的博客 4460

C++ 异常处理机制与自定义异常体系

C语言传统的错误处理机制主要有两种方式:终止程序和返回错误码。这两种方式虽然简单易用,但各自也有其局限性和缺陷,尤其是在处理复杂错误或大规模程序时,往往会导致维护上的困难。

2401_83603768的博客 4201

「C/C++」C/C++异常篇 之 异常处理

一、C语言中的异常处理 1.返回值来传递错误信息 2.使用标准库函数对异常进行处理(不推荐) 3.使用全局变量来记录错误信息(不推荐) 二、C++中的异常处理 1.try{}catch(){}异常处理 2.C++标准的异常 3.异常的重新解析(工程开发中比较实用) 4.自定义异常类

何曾参静谧的博客 1384

【C++】C++中异常及异常的使用

实际使用中很多公司都会自定义自己的异常体系进行规范的异常管理,因为一个项目中如果大家随意抛异常,那么外层的调用者基本就没办法玩了,所以实际中都会定义一套继承的规范体系。这样大家抛出的都是继承的派生类对象,捕获一个基类就可以了public:, _id(id){}protected:int _id;

zxctsclrjjjcph的博客 1383

C/C++ - 异常处理

C++异常传播(Exception Propagation)是指在程序中如果一个函数内发生了异常,而该异常没有在该函数内得到处理,则该异常会被传递到函数调用者处,如果调用者也不处理,则继续传递,这样一直到最顶层调用者。try:try​​ 块内的代码是可能产生异常的代码,当其中的代码抛出一个异常时,执行流会跳转到匹配的 catch​​ 块。当调用一个空的 std::function​​ 对象时,抛出 std::bad_function_call​​ 异常。在C语言中,错误通常通过函数的返回值来表示。

0xCC说逆向 3774

C++的异常的使用和规范

c语言的错误处理,c++的异常的使用,c++的异常的原理,c++的使用规范

m0_73693552的博客 1152

一篇文章教会你什么是C++异常

C语言传统的处理错误的方式 断言检查 返回值检查 全局错误码 设置全局错误处理函数 C++异常概念 基本概念 注意事项 异常的使用 异常的抛出和捕获 异常的重新捕获 异常安全 异常规范 自定义异常体系 C++标准库的异常体系

立志做一个高产且细节博主 1342

C/C++main函数返回值以及return 0的作用

C/C++main函数返回值以及return 0的作用 main函数的返回值 main函数的返回值用于说明程序的退出状态。如果返回0,则代表程序正常退出。返回其它数字的含义则由系统决定。通常,返回非零代表程序异常退出。 void main() 有一些书上的,都使用了void main( ) ,其实这是错误的。C/C++ 中从来没有定义过void main( ) 。C++ 之父 Bjarne St...

Xueting_B的博客 1万+

C++ 异常捕获

C++异常的捕获机制

lyzzs222的博客 7327
上一篇: 用C++ 而不是 C(3)使用跟踪语句
下一篇: WINDOWS 2K Dll 加载过程
sjf331
博客等级 码龄25年 46粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值