第十七章 用于大型程序的工具(异常处理)

    技术2025-03-26  17

     

    17.1 异常处理

    1) 抛出的异常如果是函数体中的局部变量的指针,那么当处理异常在另一个函数的时候,指针就不存在了

     

    2) 当找到匹配的catch之后,就在与该try相关的最后一个catch之后面的代码继续程序

     

    3) 析构函数应该从不抛出异常,如果在抛出异常中,再因为析构函数而抛出异常,那么会调用terminate()函数继而运行abort()函数,强制退出.

     

    4) 如果不捕获这个异常,那么将调用terminate()

     

    5) catch中可以throw;将原来的异常对象重新抛出

     

    6) catch(…)捕获所有的异常

     

    7) 构造函数的测试块

    template <class T> Handle<T>::Handle(T* p)

    try: ptr(p),use(new size_t(1))

    {}

    catch (const std::bad_alloc &e)

    {

    handle_out_of_memory(e);

    }

     

    8) 使用类来管理那些资源,可以保证在发生异常的时候可以释放资源

    例子:

    f()

    {

             int *a=new int[1000];

             //如果这中间发生了异常就悲剧了

             delete []a;

    }

     

    class A

    {

             f()

    {

             p=new int[1000];

             //就算这个时候发生异常,当退出这个类的作用域的时候,会自动调用析构函数,释放资源

             delete p;

    }

    };

     

    9) 异常类的继承表

    10) auto_ptr

    a.作用

    f()

    {

    auto_ptr<int> ap(new int (1024));

             //当出现错误,在跳出f()的时候,ap能自动析构

    }

    b.使用方式

    和正常指针一样*ap 或者ap->……..

    判断指针是否为空的时候应用if(ap.get())

    初始化或重置的时候应用ap.reset(new int (2313));//当然也可以ap.reset(0);

     

    c.赋值和对象复制的时候将出现绑定转移

    auto_ptr<int> ap1(new int (1024));

    auto_ptr<int> ap2(ap1);//这个时候ap1不指向任何对象

    auto_ptr<int> ap3(new int (1024));

    ap2=ap3;//先删除ap2指向的对象,ap2指向ap3指向的对象,ap3没有指向对象

     

    d.使用的时候的注意事项

    不能与容器类兼容(容器类需要复制)

    不能保存数组的指针(当删除的时候默认是delete,而没有delete[])

    不能保存静态成员的指针

    多个 ap不能指向同一个指针

     

    11) 异常说明

    a.类型

    void f(int) throw (runtime_error);//f()只能抛出runtime_error类或者其继承类的异常

    void f1(int) throw();//f1()不能抛出异常

    void f2(int);//f2()能抛出任何异常

     

    b.违反了规定的时候将抛出unexcepted异常导致退出

     

    c.派生类的异常说明比基类的异常说明严格

     

    d.函数指针的异常说明

    void f(int) throw (runtime_error);

    void (*fp1)(int) throw(runtime_error)=f;//ok

    void (*fp2)(int) throw()=f;//ok

    void (*fp3)(int) =f;//错了,应该更加严格才对

     

    12) 一个很简单的异常处理的例子

    摘自百度百科http://baike.baidu.com/view/1072586.htm

    #include <iostream> using namespace std; class Error { public: virtual void show()=0; }; class DenoError:public Error { public: void show() { cout<<"分母不可以为0!"<<endl; } }; void main() { int a,b; cin>>a>>b; try { DenoError e; if(b==0) throw e; int c=a/b; cout<<c<<endl; } catch(DenoError & e) { e.show(); } } 

     

     

     

     

     

     

    最新回复(0)