`
kmplayer
  • 浏览: 512738 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

异常处理之二

 
阅读更多
1,关于异常的清理.
一个特殊的情况:如果一个对象在执行构造函数的过程中抛出了异常,那么该对象的析构函数将不会被调用.导致之前动态分配的资源无法得到释放.
#include <iostream>
#include <cstddef>
using namespace std;

class A
{
public:
    A(){ cout<<"A()"<<endl; }
    ~A(){ cout<<"~A()"<<endl; }
};

class B
{
public:
    void* operator new(size_t)
    {
        cout<<"allocating B"<<endl;
        throw 43;
    }
    void operator delete(void* p) //这里的写法
    {
        cout<<"delete B"<<endl;
        ::operator delete(p);
    }
};

class UseResource
{
public:
    A* pA;
    B* pB;
    UseResource(int cnt=1)
    {
        cout<<"UseResource()"<<endl;
        pA=new A[cnt];
        pB=new B;
    }
    ~UseResource()
    {
        cout<<"~UseResource()"<<endl;
        delete[] pA;
        delete pB;
    }
};

int main()
{
    //freopen("main.txt","w",stdout);
    try{
        UseResource ur(3);
        //由于ur执行构造函数过程中发生了异常,
        //导致动态分配的资源均无法得到释放.
    }
    catch(int)
    {
        cout<<"handle int exception"<<endl;
    }
    catch( ... )
    {
        cout<<"with other exception"<<endl;
    }


    return 0;
}

引用

UseResource()
A()
A()
A()
allocating B
handle int exception

可见为A和B动态分配的资源均未得到释放.
2,利用模板类,解决上述问题.
#include <iostream>
#include <cstddef>
using namespace std;

//定义一个封装指针的典型模板类
template<class T,size_t sz=1>
class PWrap
{
public:
    T* ptr;
    PWrap()
    {
        cout<<"PWrap()"<<endl;
        ptr=new T[sz];
    }
    ~PWrap()
    {
        cout<<"~PWrap()"<<endl;
        delete[] ptr;
    }
};

class A
{
public:
    A(){ cout<<"A()"<<endl; }
    ~A(){ cout<<"~A()"<<endl; }
};

class B
{
public:
    void* operator new[](size_t)
    {
        cout<<"allocating B"<<endl;
        throw 43;
    }
    void operator delete[](void* p) //这里的写法
    {
        cout<<"delete B"<<endl;
        ::operator delete[](p);
    }
};

class UseResource
{
public:
    PWrap<A,3> a; //这里分配的资源均得到了释放.
    PWrap<B> b; //抛出了异常
    //模板的使用使得ur在调用构造函数之前,
    //A,B的构造函数首先被调用,因此在"栈反解"
    //的时候,会调用析构函数.
    UseResource(int cnt=1)
    {
        cout<<"UseResource()"<<endl;
    }
    ~UseResource()
    {
        cout<<"~UseResource()"<<endl;
    }
};

int main()
{
    freopen("main.txt","w",stdout);
    try{
        UseResource ur(3);
        //由于ur执行构造函数过程中发生了异常,
        //导致动态分配的资源均无法得到释放.
    }
    catch(int)
    {
        cout<<"handle int exception"<<endl;
    }
    catch( ... )
    {
        cout<<"with other exception"<<endl;
    }


    return 0;
}


引用
PWrap()
A()
A()
A()
PWrap()
allocating B
~PWrap()
~A()
~A()
~A()
handle int exception

由输出可以看出为a分配的资源均得到了释放.
但是由于异常发生在b的构造函数,因此对象b和它的模板类均未调用析构函数.
分享到:
评论

相关推荐

    异常处理 异常处理 异常处理

    异常处理是编程中的一种机制,用于捕获和处理运行时发生的错误或异常情况。异常可以由硬件引发,如硬件异常,也可以由操作系统或应用程序自身触发,即软件异常。当异常发生时,操作系统允许程序有机会检查异常类型并...

    C#异常处理总结及简单实例

    C# 异常处理时建立在四个关键词之上的:try、catch、finally 和 throw。 1、try:一个 try 块标识了一个将被激活的特定的异常的代码块。后跟一个或多个 catch 块。 2、catch:程序通过异常处理程序捕获异常。catch ...

    java异常处理习题

    二、异常处理机制 * 异常是一种对象,继承自 `Throwable` 类。 * 异常处理的主要步骤是:抛出异常(throw) -&gt; 捕捉异常(catch) -&gt; 处理异常(finally)。 三、异常类的继承关系 * `Throwable` 是所有异常类的...

    C++ 异常处理 C++ 异常处理

    ### C++异常处理详解 #### 引言 随着软件项目的规模不断扩大,确保软件质量变得日益复杂且至关重要。软件产品在实际应用中面临多种潜在风险,包括但不限于程序崩溃、数据丢失等,这些问题严重影响用户体验及系统...

    MySQL定义异常和异常处理详解

    2. **异常处理** 异常处理则是定义当异常发生时如何应对。处理方式可以通过`DECLARE HANDLER`语句来设置,可以指定在出现特定异常时执行的语句。处理方式有三种:`CONTINUE`、`EXIT`和`UNDO`。 - `CONTINUE`:遇到...

    异常处理.ppt异常处理.ppt异常处理.ppt异常处理.ppt异常处理.ppt

    2. **异常处理的特点**: - **隔离错误处理代码**:异常处理允许我们将可能出错的代码与正常执行的代码分开,提高代码的可读性和可维护性。例如,在读取文件的代码中,可以将错误处理逻辑与读取文件的主要逻辑分离...

    Struts2之异常处理案例struts003

    在Struts2中,异常处理是一项重要的功能,它确保在应用程序遇到错误时能够优雅地处理,提供友好的用户反馈,并保持系统稳定性。下面将详细讨论Struts2中的异常处理机制及其相关知识点。 1. **异常处理机制概述** ...

    ADS异常处理.pptADS异常处理.pptADS异常处理.ppt

    二、异常处理流程 当异常发生时,ARM处理器遵循以下步骤: 1. 保存状态:将当前程序状态寄存器(CPSR)复制到对应的保存程序状态寄存器(SPSR)。 2. 模式切换:根据异常类型切换到相应的异常模式,如FIQ模式、IRQ...

    Struts2异常处理机制

    Struts2作为一款流行的Java Web框架,其异常处理机制是其核心功能之一,它使得开发者能够优雅地管理和处理应用程序中的异常情况,提供了一种统一的错误处理方式,从而提高用户体验并增强程序的健壮性。 在Struts2...

    使用Spring AOP对异常进行统一处理

    3.处理日志时,需要在每一个try-catch块包含一些处理代码,有时候异常处理的代码比正常执行代码还多,污染正常执行代码。 4.同样类型异常有不同的处理方式,使最终的处理变得复杂。 5.接口抛出异常,破坏封装,打破...

    ARM处理器异常处理步骤

    ARM处理器异常处理是指ARM微处理器对各种异常情况作出响应和处理的过程。异常指的是处理器在正常执行程序时遇到的特殊情况,例如外部中断请求、未对齐的内存访问错误、指令预取终止等。为了保证系统的稳定性和正确性...

    易语言SEH异常处理

    2. **异常处理结束**:一旦异常被处理,程序需要有一个机制来标记异常处理的结束,恢复正常执行流程。在易语言中,这通常涉及解除已注册的异常处理器,并恢复到异常发生前的状态。 3. **GetEip**:在异常发生时,...

    Windows下的异常处理

    2. 查找异常处理程序:处理器会沿着调用堆栈向上查找异常处理程序(通常是一个函数),该程序负责处理异常。 3. 异常过滤器:在找到异常处理程序后,会执行异常过滤器代码,该代码可以决定如何处理异常。过滤器可能...

    高效的java异常处理框架高效的java异常处理框架高效的java异常处理框架

    2、异常处理逻辑:设计合适的异常处理逻辑,尽量恢复程序的正常运行。 3、异常记录:记录异常的信息,以便后续的分析和 debug。 4、异常测试:对异常处理逻辑进行测试,确保程序的健壮性。 设计一个高效的 Java ...

    JCVM异常处理机制

    #### 二、异常处理表结构分析 在JCVM规范中,由于智能卡平台计算资源极其有限(例如,RAM通常只有1kB,EEPROM为16kB),因此采用了内外结合的虚拟机实现方式。即外部虚拟机负责将标准Java编译器生成的`.class`文件...

    异常处理流程图Exception

    在IT领域,特别是软件开发过程中,异常处理是确保程序健壮性和用户友好体验的关键环节。异常处理机制允许程序在遇到意外情况时,能够有条不紊地进行错误处理,而不是直接崩溃或产生不可预知的结果。本文将深入探讨...

    异常处理机制知识点小总结

    异常处理是Java编程中至关重要的一个概念,它确保了程序在遇到错误或异常情况时能够以优雅的方式继续执行或者终止。下面是对Java异常处理机制的详细解析。 在Java中,异常是程序运行时发生的错误,它中断了正常的...

    Spring Cloud Gateway的全局异常处理

    #### 二、Spring Cloud Gateway全局异常处理原理 Spring Cloud Gateway默认使用`DefaultErrorWebExceptionHandler`类来处理异常,该类继承自`AbstractErrorWebExceptionHandler`,并在内部使用了`ErrorAttributes`...

    使用企业库进行异常处理

    2. **策略定义与维护**:异常处理策略可以在高层定义,由系统管理员或开发人员决定如何处理异常,通过配置而非代码进行修改。 3. **内置异常处理功能**:包括记录异常信息、替换异常以隐藏敏感信息、包装异常以添加...

Global site tag (gtag.js) - Google Analytics