C++构造函数、析构函数与抛出异常

来源:互联网 发布:淘宝店免费代理货源 编辑:程序博客网 时间:2024/05/20 04:26
  1. 请问构造函数后面的throw()含义 :
    • 在构造时,可能会抛出异常
      使用时,要注意用try和catch
  2. 解释:

    • 标准C++中定义构造函数是一个对象构建自己,分配所需资源的地方,一旦构造函数执行完毕,则表明这个对象已经诞生了,有自己的行为和内部的运行状态,之后还有对象的消亡过程(析构函数的执行)。可谁能保证对象的构造过程一定能成功呢?说不定系统当前的某个资源不够,导致对象不能完全构建好自己,又由于C++标准规定构造函数是没有返回值,因为构造函数没有返回值,所以通知对象的构造失败的唯一方法那就是在构造函数中抛出异常。
    • 构造函数中抛出异常时概括性总结 :
      • 1) C++中通知对象构造失败的唯一方法那就是在构造函数中抛出异常;
      • 2) 构造函数中抛出异常将导致对象的析构函数不被执行;
      • 3) 当对象发生部分构造时,已经构造完毕的子对象将会逆序地被析构;
      • 4) 其是还是那句话, “C++的异常处理不会破坏任何一条面向对象的特性!”。
  3. 额外的资源链接

    • http://www.cnblogs.com/hellogiser/p/constructor-destructor-exceptions.html
  4. 上述链接的内容:构造函数可以抛出异常么?析构函数可以吗?

  1. 构造函数可以抛出异常么?析构函数可以吗?
  2. 分析:
    • 从语法上来说,构造函数和析构函数都可以抛出异常。但从逻辑上和风险控制上,构造函数可以,析构函数不推荐抛出异常。
  3. (1)构造函数可以抛出异常:

    • 无论何时,从构造函数中抛出异常都是可以的。动态创建对象要进行两个操作:分配内存和调用构造函数。若在分配内存时出错,会抛出bad_alloc异常;若在调用构造函数初始化时出错,会不会存在内存泄漏呢?答案是不会。
    • new运算符保证不会出现内存泄漏:
      T *p = new T;

    将被编译器转换给类似下面的样子:

        void allocate_and_construct()    {        // 第一步,分配原始内存,若失败则抛出bad_alloc异常        try        {            // 第二步,调用构造函数构造对象            new (p)T;       // placement new: 只调用T的构造函数        }        catch(...)        {            delete p;     // 释放第一步分配的内存            throw;          // 重抛异常,通知应用程序        }    }
  4. (2)析构函数不推荐抛出异常,如果析构函数可能抛出异常,那么必须要求在析构函数内消化所有异常或者结束程序。

    • more effective c++提出两点理由(析构函数不能抛出异常的理由)
    • 1)如果析构函数抛出异常,则异常点之后的程序不会执行,如果析构函数在异常点之后执行了某些必要的动作比如释放某些资源,则这些动作不会执行,会造成诸如资源泄漏的问题。 [正常情况下调用析构函数抛出异常导致资源泄露]
    • 2)通常异常发生时,c++的机制会调用已经构造对象的析构函数来释放资源,此时若析构函数本身也抛出异常,则前一个异常尚未处理,又有新的异常,会造成程序崩溃的问题。 [在发生异常的情况下调用析构函数抛出异常,会导致程序崩溃]
    • 解决方案:
      • 1) 如果某个操作可能会抛出异常,class应提供一个普通函数(而非析构函数),来执行该操作。目的是给客户一个处理错误的机会。
      • 2) 如果析构函数中异常非抛不可,那就用try catch来将异常吞下,必须要把这种可能发生的异常完全封装在析构函数内部,决不能让它抛出函数之外。
原创粉丝点击