错误处理和异常处理,你用哪一个

CArchive源码分析 CArchive的功能: 1.CArchive封装了文件的读写操作,使文件读写变的更简单,其内部重载了> 使读写文件如使用cin cout一样 2.CArchive提供了缓存机制,使文件操作更高效 3.CArchive不仅只是封装文件操作,他还能够结合CMemFile  和 CSocketFile(这些都是CFile的派生类),使对其操作也更简化 先看下对DWORD写操作代码: _AFX 阅读详情
转自: http://blog.youkuaiyun.com/lyzhm/archive/2007/01/20/1488560.aspx
张笑猛
2003年1月
1.简介
    异常是由语言提供的运行时刻错误处理的一种方式。提到错误处理,即使不提到异常,你大概也已经有了丰富的经验,但是为了可以清楚的看到异常的好处,我们还是不妨来回顾一下常用的以及不常用的错误处理方式。

1.1 常用的错误处理方式
返回值。我们常用函数的返回值来标志成功或者失败,甚至是失败的原因。但是这种做法最大的问题是如果调用者不主动检查返回值也是可以被编译器接受的,你也奈何不了他:) 这在C++中还导致另外一个问题,就是重载函数不能只有不同的返回值,而有相同的参数表,因为如果调用者不检查返回值,则编译器会不知道应该调用哪个重载函数。当然这个问题与本文无关,我们暂且放下。只要谨记返回值可能被忽略的情况即可。

全局状态标志。例如系统调用使用的errno。返回值不同的是,全局状态标志可以让函数的接口(返回值、参数表)被充分利用。函数在退出前应该设置这个全局变量的值为成功或者失败(包括原因),而与返回值一样,它隐含的要求调用者要在调用后检查这个标志,这种约束实在是同样软弱。全局变量还导致了另外一个问题,就是多线程不安全:如果多个线程同时为一个全局变量赋值,则调用者在检查这个标志的时候一定会非常迷惑。如果希望线程安全,可以参照errno的解决办法,它是线程安全的。

1.2 不常用的处理方式
setjmp()/longjmp()。可以认为它们是远程的goto语句。根据我的经验,它们好象确实不常被用到,也许是多少破坏了结构化编程风格的原因吧。在C++中,应该是更加的不要用它们,因为致命的弱点是longjmp()虽然会unwinding stack(这个词后面再说),但是不会调用栈中对象的析构函数--够致命吧。对于不同的编译器,可能可以通过加某个编译开关来解决这个问题,但太不通用了,会导致程序很难移植。

1.3 异常
现在我们再来看看异常能解决什么问题。对于返回值和errno遇到的尴尬,对异常来说基本上不存在,如果你不捕获(catch)程序中抛出的异常,默认行为是导致abort()被调用,程序被终止(core dump)。因此你的函数如果抛出了异常,这个函数的调用者或者调用者的调用者,也就是在当前的call stack上,一定要有一个地方捕获这个异常。而对于setjmp()/longjmp()带来的栈上对象不被析构的问题对异常来说也是不存在的。那么它是否破坏了结构化(对于OO paradigms,也许应该说是破坏了流程?)呢?显然不是,有了异常之后你可以放心的只书写正确的逻辑,而将所有的错误处理归结到一个地方,这不是更好么?

综上所述,在C++中大概异常可以全面替代其它的错误处理方式了,可是如果代码中到处充斥着try/throw/catch也不是件好事,欲知异常的使用技巧,请保持耐心继续阅读:)

2. 异常的语法
在这里我们只讨论一些语法相关的问题。

2.1 try
try总是与catch一同出现,伴随一个try语句,至少应该有一个catch()语句。try随后的block是可能抛出异常的地方。

2.2 catch
catch带有一个参数,参数类型以及参数名字都由程序指定,名字可以忽略,如果在catch随后的block中并不打算引用这个异常对象的话。参数类型可以是build-in type,例如int, long, char等,也可以是一个对象,一个对象指针或者引用。如果希望捕获任意类型的异常,可以使用“...”作为catch的参数。

catch不一定要全部捕获try block中抛出的异常,剩下没有捕获的可以交给上一级函数处理。

2.3 throw
throw后面带一个类型的实例,它和catch的关系就象是函数调用,catch指定形参,throw给出实参。编译器按照catch出现的顺序以及catch指定的参数类型确定一个异常应该由哪个catch来处理。

throw不一定非要出现在try随后的block中,它可以出现在任何需要的地方,只要最终有catch可以捕获它即可。即使在catch随后的block中,仍然可以继续throw。这时候有两种情况,一是throw一个新类型的异常,这与普通的throw一样。二是要rethrow当前这个异常,在这种情况下,throw不带参数即可表达。例如:

try{
    ...
}
catch(int){
    throw MyException("hello exception");    // 抛出一个新的异常
}
catch(float){
    throw;                   // 重新抛出当前的浮点数异常
}

2.4 函数声明
还有一个地方与throw关键字有关,就是函数声明。例如:

void foo() throw (int);      // 只能抛出int型异常
void bar() throw ();         // 不抛出任何异常
void baz();                  // 可以抛出任意类型的异常或者不抛出异常

如果一个函数的声明中带有throw限定符,则在函数体中也必须同样出现:

void foo() throw (int)
{
    ...
}

这里有一个问题,非常隐蔽,就是即使你象上面一样编写了foo()函数,指定它只能抛出int异常,而实际上它还是可能抛出其他类型的异常而不被编译器发现:

void foo() throw (int)
{
    throw float;     // 错误!异常类型错误!会被编译器指出
    ...
    baz();           // 正确!baz()可能抛出非int异常而编译器又不能发现!
}

void baz()
{
    throw float;
}

这种情况的直接后果就是如果baz()抛出了异常,而调用foo()的代码又严格遵守foo()的声明来编写,那么程序将abort()。这曾经让我很恼火,认为这种机制形同虚设,但是还是有些解决的办法,请参照“使用技巧”中相关的问题。

3. 异常使用技巧

3.1 异常是如何工作的
为了可以有把握的使用异常,我们先来看看异常处理是如何工作的。

3.1.1 unwinding stack
我们知道,每次函数调用发生的时候,都会执行保护现场寄存器、参数压栈、为被调用的函数创建堆栈这几个对堆栈的操作,它们都使堆栈增长。每次函数返回则是恢复现场,使堆栈减小。我们把函数返回过程中恢复现场的过程称为unwinding stack。

异常处理中的throw语句产生的效果与函数返回相同,它也引发unwinding stack。如果catch不是在throw的直接上层函数中,那么这个unwinding的过程会一直持续,直到找到合适的catch。如果没有合适的catch,则最后std::unexpected()函数被调用,说明发现了一个没想到的异常,这个函数会调用std::terminate(),这个terminate()调用abort(),程序终止(core dump)。

在“简介”中提到的longjmp()也同样会unwinding stack,但是这是一个C函数,它就象free()不会调用对象的析构函数一样,它也不知道在unwinding stack的过程中调用栈上对象的析构函数。这是它与异常的主要区别。

3.1.2 RTTI
在unwinding stack的过程中,程序会一直试图找到一个“合适”的catch来处理这个异常。前面我们提到throw和catch的关系很象是函数调用和函数原型的关系,多个catch就好象一个函数被重载为可以接受不同的类型。根据这样的猜测,好象找到合适的catch来处理异常与函数重载的过程中找到合适的函数原型是一样的,没有什么大不了的。但实际情况却很困难,因为重载的调用在编译时刻就可以确定,而异常的抛出却不能,考虑下面的代码:

void foo() throw (int)
{
    throw int;
}

void bar()
{
    try{
        foo();
    }
    catch(int){
        ...
    }
    catch(float){
        ...
    }
}

void baz()
{
    try{
        foo();
    }
    catch(int){
        ...
    }
    catch(float){
        ...
    }
}

foo()在两个地方被调用,这两次异常被不同的catch捕获,所以在为throw产生代码的时候,无法明确的指出要由哪个catch捕获,也就是说,无法在编译时刻确定。

仍然考虑这个例子,让我们来看看既然不能在编译时刻确定throw的去向,那么在运行时刻如何确定。在bar()中,一列catch就象switch语句中的case一样排列,实际上是一系列的判断过程,依次检查当前异常的类型是否满足catch指定的类型,这种动态的,在运行时刻确定类型的技术就是RTTI(Runtime Type Identification/Information)。深度探索C++对象模型[1]中提到,RTTI就是异常处理的副产品。关于RTTI又是一个话题,在这里就不详细讨论了。

3.2 是否继承std::exception?
是的。而且std::exception已经有了一些派生类,如果需要可以直接使用它们,不需要再重复定义了。

3.3 每个函数后面都要写throw()?
尽管前面已经分析了这样做也有漏洞,但是它仍然是一个好习惯,可以让调用者从头文件得到非常明确的信息,而不用翻那些可能与代码不同步的文档。如果你提供一个库,那么在库的入口函数中应该使用catch(...)来捕获所有异常,在catch(...)中捕获的异常应该被转换(rethrow)为throw列表中的某一个异常,这样就可以保证不会产生意外的异常。

3.4 guard模式
异常处理在unwinding stack的时候,会析构所有栈上的对象,但是却不会自动删除堆上的对象,甚至你的代码中虽然写了delete语句,但是却被throw跳过,导致内存泄露,或者其它资源的泄露。例如:

void foo()
{
    ...
    MyClass * p = new MyClass();
    bar(p);
    ...
    delete p;       // 如果bar()中抛出异常,则不会运行到这里!
}

void bar(MyClass * p)
{
    throw MyException();
}

对于这种情况,C++提供了std::auto_ptr这个模板来解决问题。这个常被称为“智能指针”的模板原理就是,将原来代码中的指针用一个栈上的模板实例保护起来,当发生异常unwinding stack的时候,这个模板实例会被析构,而在它的析构函数中,指针将被delete,例如:

void foo()
{
    ...
    std::auto_ptr<MyClass>; p(new MyClass());
    bar(p.get());
    ...
    // delete p;       // 这句不再需要了
}

void bar(MyClass * p)
{
    throw MyException();
}

不论bar()是否抛出异常,只要p被析构,内存就会被释放。

不光对于内存,对于其他资源的管理也可以参照这个方法来完成。在ACE[2]中,这种方式被称为Guard,用来对锁进行保护。

3.5 构造函数和析构函数
构造函数没有返回值,很多地方都推荐通过抛出异常来通知调用者构造失败。这是肯定是个好的办法,但是也不很完美。主要是因为在构造函数中抛出异常并不会引发析构函数的调用,例如:

class foo
{
public:
    ~foo() {} // 这个函数将被调用
};

class bar
{
public:
    bar() { c_ = new char[10]; throw -1;}
    ~bar() { delete c_;}  // 这个函数不会被调用!
private:
    char * c_;
    foo f_;
};

void baz()
{
    try{
        bar b;
    }
    catch(int){
    }
}

在这个例子中,bar的析构函数不会被调用,但是尽管如此,foo的析构函数还是可以被调用。危险的是在构造函数中分配空间的c_,因为析构函数没有被调用而变成了leak。最好的解决办法还是auto_ptr,使用auto_ptr后,bar类的声明变成:

class bar
{
public:
    bar() { c_.reset(new char[10]); throw -1;}
    ~bar() { }  // 不需要再delete c_了!
private:
    auto_ptr<char>; c_;
    foo f_;
};

析构函数中则不要抛出异常,这一点在Thinking In C++ Volume 2[3]中有明确表述。如果析构函数中调用了可能抛出异常的函数,则应该在析构函数内部catch它。

3.6 什么时候使用异常
到现在为止,我们已经讨论完了异常的大部分问题,可以实际操作操作了。实际应用中遇到的最让我头疼的问题就是什么时候应该使用异常,是否应该用异常全面代替“简介”中提到的其它错误处理方式呢?

首先,不能用异常完全代替返回值,因为返回值的含义不一定只是成功或失败,有时候是一个可选择的状态,例如:

if(customer->;status() == active){
    ...
}
else{
    ...
}

在这种情况下,不论返回值是什么,都是程序可以接受的正常的结果。而异常只能用来表达“异常”-- 也就是错误的状态。这好象是显而易见的事情,但是实际编程的过程中有很多更加模棱两可的时候,遇到这样的情况,首先要考虑的就是这个原则。

第二,看看在特定的情况下异常是否会发挥它的优点,而这个优点正好又不能使用其他技术达到(或者简单的达到)。比如,如果你正在为电信公司写一个复杂计费逻辑,那么你当然希望在整个计算费用的过程中集中精力去考虑业务逻辑方面的问题,而不是到处需要根据当前返回值判断是否释放前面步骤中申请的资源。这时候使用异常可以让你的代码非常清晰,即使你有100处申请资源的地方,只要一个地方集中释放他们就好了。例如:

bool bar1();
bool bar2();
bool bar3();

bool foo()
{
    ...
    char * p1 = new char[10];
    ...
    if(!bar1()){
        delete p1;
        return false;
    }
    ...
    char * p2 = new char[10];
    ...
    if(!bar2()){
        delete p1;             // 要释放前面申请的所有资源
        delete p2;
        return false;
    }
    ...
    char * p3 = new char[10];
    ...
    if(!bar2()){
        delete p1;             // 要释放前面申请的所有资源
        delete p2;
        delete p3;
        return false;
    }
}

这种流程显然不如:

void bar1() throw(int);
void bar2() throw(int);
void bar3() throw(int);

void foo() throw (int)
{
    char * p1 = NULL;
    char * p2 = NULL;
    char * p3 = NULL;
    try{
        char * p1 = new char[10];
        bar1();
        char * p2 = new char[10];
        bar2();
        char * p3 = new char[10];
        bar3();
    }
    catch(int){
        delete p1;        // 集中释放资源
        delete p2;
        delete p3;
        throw;
    }
}

第三,在Thinking In C++ Volume 2[3]中列了一个什么时候不应该用,什么时候应该用的表,大家可以参考一下。

最后,说一个与异常无关的东西,但也跟程序错误有关的,就是断言(assert),我在开发中使用了异常后,很快发现有的人将应该使用assert处理的错误定义成了异常。这里稍微提醒一下assert的用法,非常简单的原则:只有对于那些可以通过改进程序纠正的错误,才可以用assert。返回值、异常显然与其不在一个层面上,这是C的入门知识。
【第七天】C++异常的抛出、捕获以及标准异常库 异常:是指在程序运行的过程中发生的一些异常事件(如:除0溢出,数组下标越界,所要 读取的文件不存在,空指针,内存不足,访问非法内存等等)。(异常是一个类。)异常处理就是处理程序中的错误。 阅读详情

相关推荐

如何进行错误处理和异常处理?

在开始详细讨论错误处理和异常处理之前,让我们先了解一下错误和异常的概念。错误:错误通常是指在程序执行过程中出现的问题,导致程序无法按预期方式继续运行。错误可以分为编译时错误和运行时错误。编译时错误是在编译代码时发现的,通常是语法错误或类型错误。而运行时错误是在程序执行时发生的,可能是由于不合法的输入、资源不足、内存溢出等原因引起的。异常:异常是一种特殊类型的错误,它通常与程序的逻辑错误或不正常情况相关。异常通常是由于程序状态不一致或不合法操作引起的。

weixin_68551689的博客 1452

C++异常(exception)

​ 所谓的异常就是不正常,指在程序运行的过程中,由于系统条件、操作不当等原因所引起的程序运行错误​ 常见的异常:除零错误、指针访问受保护的空间、数组越界、内存分配失败、打开的文件不错在…在C++中,新增加了一种错误(异常)处理方式编译时错误:在程序编译阶段就能够发现的错误运行时错误:编译能够通过,在运行的时候会有一些错误产生为了提高系统的健壮性,加强容错能力,在编程过程中,这些错误(异常)必须要处理,防止系统崩溃。

weixin_56169816的博客 4267

C++编程法则365天一天一条(15)C++异常如何写

您可以通过继承和重载exception类来定义新的异常。

二进制君 873

【C++】异常exception

异常详解

Hello_World_213的博客 3616

Ubuntu 24.04 部署 EMQX 5.8 开源版MQTT服务器:从零搭建到实战应用

本文详细指导如何在Ubuntu 24.04系统上部署EMQX 5.8开源版MQTT服务器。内容涵盖从环境准备、安装Erlang、下载安装包到启动服务的完整步骤,并提供了验证服务、配置网络防火墙以及通过WebSocket工具进行基础消息收发的实战方法,帮助用户快速搭建稳定、免费的物联网消息中间件。

weixin_29209825的博客 293

vivado下ECO操作-不重新综合实现修改属性并生成.bit

ECO即engineer change order,即工程变更指令,可以对设计做局部小改动并只对改动部分重新布局布线并生成.bit。在一个工程动辄编译几个小时情况下,可以在调试中节省大量时间。比如我们在调试中,需要改变时钟占空比或者相位,需要改变寄存器初值等等,此时用ECO暂时改动,待验证后在重新编译无疑是最有效率的方法。 实现ECO通常有两种方式,一是通过vivado界面完成,另一种方法就是tcl脚本。所有的ECO操作都可以通过tcl操作完成,有的操作用vivado界面无法完成,只能通过tcl。以下主要

4662

php错误处理和异常处理,PHP的错误处理和异常处理

由于教程是围绕着文件打开做的错误处理,所以先记录几个用于文件处理的一些函数,fopen 用于打开一个文件;file_exists 用于检查目录是否存在;fclose( $变量 )用于指定关闭打开的文件;PHP处理错误的几种方式:die()语句;自定义错误和错误触发器;错误日志;die()语句:eg :file_exists ( “文件路径/文件名” ) or die( "文件不存在" );自定义错...

weixin_29243063的博客 305

告别配置烦恼!保姆级教程:在Windows 10/11上为QT5.14.2配置MSVC2017编译器(附VS2022组件避坑指南)

本文提供了一份详细的保姆级教程,指导如何在Windows 10/11上为QT5.14.2配置MSVC2017编译器,包括VS2022组件避坑指南。从环境准备到关键配置,再到调试工具验证和Qt Creator中的编译器设置,一步步解决常见问题,帮助开发者快速搭建稳定可靠的开发环境。

weixin_30615767的博客 503

异常处理和错误处理技术

3. 不捕获异常,使用throws声明:在方法签名中使用throws关键字声明可能抛出的异常类型,将异常的处理责任交给调用者。- 自定义异常类型:可以根据程序的需求定义自己的异常类型,通过继承现有的异常类型来创建自定义异常类。- 异常处理应提供有意义的错误消息和适当的处理策略,以帮助开发人员和用户理解异常的原因和解决方案。- 异常信息的记录:记录异常信息,包括异常类型、异常消息、堆栈跟踪等,以便进行问题排查和修复。- 明确处理异常:在可能发生异常的地方进行异常处理,避免异常传递到程序的其他部分。

m0_75198698的博客 1075

基于FPGA的DDR学习——1.基础知识

⚪DDR2(Double Data Rate2)SDRAM是由JEDEC(电子设备工程联合委员会)开发的第三代SDRAM内存技术标准,1.8V工作电压,240线接口,提供了相较于DDR SDRAM更高的运行效能与更低的电压,同样采用在时钟的上升/下降沿同时进行数据传输的基本方式,但拥有两倍于上一代DDR内存预读取能力(即4bit数据预取能力),其常见的频率规范有DDR2 400\533\667\800\1066\1333等,总线频率553MHZ的DDR2内存只需133MHZ的工作频率。

qq_44932488的博客 2072

Unity URP风格化水面Shader全流程实现与性能优化指南

在游戏开发中,Shader是实现特定视觉风格的核心技术,它通过编写在GPU上运行的程序,控制模型每个像素的最终颜色与光照表现。其原理在于对顶点位置、纹理坐标、光照信息及深度等数据进行一系列数学运算与插值。这项技术的价值在于能够以极高的自由度创造从写实到卡通的各种渲染效果,同时通过算法优化实现对硬件资源的精准控制。在移动游戏、独立游戏等对性能与风格化有强烈需求的场景中,自定义Shader尤为重要。本文聚焦于使用Unity URP渲染管线,从零构建一个高效的风格化水面Shader,详细拆解了深度色、波浪动画、边

weixin_34320724的博客 372

php错误处理和php异常处理机制

将错误报告写入日志中 一、指定错误报告 error_reporting = E_LL 二、关闭错误输出 display_errors = Off 三、开启错误日志功能 log_errors = On 1. 默认如果不指定错误日志位置,则默认写WEB服务器的日志中 2. 为error_log选项指定 一个文件名(可写) 3. 写入到操作系统日志中error_log=syslog 异常处理: 意外,是在程序运行过程中发生的意料这外的事,使用异常改变脚本正常流程

NiceGY 2312

PHP的错误处理和异常处理

  由于教程是围绕着文件打开做的错误处理,所以先记录几个用于文件处理的一些函数,fopen 用于打开一个文件;file_exists 用于检查目录是否存在;fclose( $变量 )用于指定关闭打开的文件;   PHP处理错误的几种方式:die()语句;自定义错误和错误触发器;错误日志;   die()语句:     eg :file_exists ( “文件路径/文件名” ) o...

dianzhilian6452的博客 197

禅道二次开发(一):从零搭建本地开发与调试环境

本文详细介绍了禅道二次开发的第一步:从零搭建本地开发与调试环境。通过部署官方一键安装包、配置端口与防火墙、连接数据库、设置Samba文件共享,并最终在VSCode中配置PHP智能感知与Xdebug调试,手把手教你建立一个隔离、高效的专属开发工作台,为后续的代码修改与功能扩展奠定坚实基础。

weixin_29003437的博客 323

ABB机器人与S7-1200PLC实现位置坐标数据发送和接收的具体方法

ABB机器人与S7-1200PLC实现位置坐标数据发送和接收的具体方法

Robot_PLC_HMI_Automation 2918

JVM 的异常处理和错误处理机制

JVM)是Java程序的运行环境,它负责将Java字节码转换为机器码并执行。在Java程序运行过程中,可能会出现各种异常(Exception)和错误(Error),JVM提供了异常处理和错误处理机制来处理这些异常和错误,保证程序的稳定性和可靠性。

互联网知识分享 948

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C++异常处理机制和传统的错误处理机制相比较有哪些有点

异常处理:通过`try`、`catch`、`throw`关键字,可以在代码的任意位置抛出异常,并在其他地方捕获处理。传统错误处理:通常使用返回值或全局变量来表示错误状态,错误处理代码通常与正常代码混合在一起,可能导致代码混乱。异常处理:虽然异常处理提供了许多优点,但它也增加了代码的复杂性,尤其是在大型项目中,需要仔细设计异常处理策略。异常处理:异常是类型化的,每个异常都是一个对象,这允许捕获特定类型的异常,并提供更丰富的错误信息。传统错误处理:在某些情况下,错误处理是强制性的,因为函数需要返回错误状态。

qq_57045429的博客 312

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

PHP 中的错误处理和调试:PHP 中的异常处理

PHP 中的异常处理是一种机制,它允许开发人员有效地管理和响应 PHP 脚本执行过程中可能发生的运行时错误或异常情况。通过使用 try-catch 块,开发人员可以隔离和处理特定的异常,防止它们导致脚本突然终止。异常处理支持优雅的错误处理,提高代码可靠性,并允许自定义错误消息或操作。通过适当的异常处理,开发人员可以以结构化的方式识别和处理错误,从而获得更可靠和可维护的 PHP 应用程序。在 PHP 中,异常是一个对象,表示在执行 PHP 脚本期间发生的异常事件或错误。

新华编程特战队 817

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

php错误处理和异常处理

PHP错误处理有两种:标准的错误处理和异常(OOP语法新出现的错误处理机制) 标准错误是由:错误等级,错误信息,错误发生文件,与错误发生行号组成。php提供了多种错误等级,用来描述错误的重要程度。 标准错误两种触发形式:php自动触发: php检测到存在一个错误,则会将错误触发用户脚本触发:利用内置函数trigger_error('错误消息','错误级别');错误级别只能使用常量来表示:默...

weixin_30315723的博客 142

错误处理和异常处理在网络编程中的重要性

错误处理和异常处理在网络编程中的重要性

深耕嵌入式领用多年, 致力于分享嵌入式领域技术! 494

错误处理和异常处理,你用哪一个[转载]

张笑猛2003年1月1.简介    异常是由语言提供的运行时刻错误处理的一种方式。提到错误处理,即使不提到异常,你大概也已经有了丰富的经验,但是为了可以清楚的看到异常的好处,我们还是不妨来回顾一下常用的以及不常用的错误处理方式。1.1 常用的错误处理方式返回值。我们常用函数的返回值来标志成功或者失败,甚至是失败的原因。但是这种做法最大的问题是如果调用者不主动检查返回值也是可以被编译器接受的,你也奈

lyzhm的专栏 1284
上一篇: 为什么最好在c++中使用异常
下一篇: 使用异常和返回值,Exception and Error dispose
UU_Yang
博客等级 码龄23年 926粉丝 213原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值