我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:金算盘心水论坛 > 抛出异常 >

c++构造函数抛出异常怎么处理

归档日期:08-07       文本归类:抛出异常      文章编辑:爱尚语录

  1、标准C++中定义构造函数是一个对象构建自己,分配所需资源的地 方,一旦构造函数执行完毕,则表明这个对象已经诞生了,有自己的行为和内部的运行状态,之后还有对象的消亡过程(析构函数的执行)。可谁能保证对象的构造 过程一定能成功呢?说不定系统当前的某个资源不够,导致对象不能完全构建好自己(人都有畸形儿,更何况别的呢?朋友们!是吧!),因此通过什么方法来表明 对象的构造失败了呢?C++程序员朋友们知道,C++中的构造函数是没有返回值的,所以不少关于C++编程方面的书上得出结论:“因为构造函数没有返回 值,所以通知对象的构造失败的唯一方法那就是在构造函数中抛出异常”。主人公阿愚非常不同意这种说法,谁说的,便不信邪!虽然C++标准规定构造函数是没 有返回值,可我们知道每个函数实际上都会有一个返回值的,这个值被保存在eax寄存器中,因此实际上是有办法通过编程来实现构造函数返回一个值给上层的对 象创建者。当然即便是构造函数真的不能有返回值,我们也可以通过一个指针类型或引用类型的出参来获知对象的构造过程的状态。示例如下:

  是啊!上面我们不也得到了对象构造的成功与否的信息了吗?可大家有没有觉得这当中有点问题?建议在此停留片刻,仔细想想它会有什么问题?OK!也许大家都知道了问题的所在,来验证一下吧!

  没错,对象的析构函数被运行了,这与C++标准中所规定的面向对象的一些特性是有冲突的。一个对象都没有完成自己的构造,又何来析构!好比一个 夭折的畸形儿还没有出生,又何来死之言。因此这种方法是行不通的。那怎么办?那就是上面那个结论中的后一句话是对的,通知对象的构造失败的唯一方法那就是 在构造函数中抛出异常,但原因却不是由于构造函数没有返回值而造成的。恰恰相反,C++标准中规定构造函数没有返回值正是由于担心很容易与面向对象的一些 特性相冲突,因此干脆来个规定,构造函数不能有返回值

  2、构造函数中抛出异常将导致对象的析构函数不被执行。如果没有C++的异常处理机制鼎立支持,C++中的面向 对象特性都无法真正实现起来,C++标准总不能规定所有的对象都必须成功构造吧!这也太理想化了,也许只有等到社会实现的那一天(CPU可以随便 拿,内存可以随便拿,所有的资源都是你的!)才说不定有可能·····,所以说C++的异常处理和面向对象确实是谁也离不开谁。当然示例还是要看一下,如 下:

  程序的运行结果将会验证:“构造函数中抛出异常将导致对象的析构函数不被执行”

  3、是不是到此,关于构造函数中抛出异常的处理的有关讨论就能结束了呢?非也!非也!主人公阿愚还有进一步的故事需要讲述!来看一个更复杂一点的例子吧!如下:

  上面这个例子中,MyTest_Derive从MyTest_Base继承,同时MyTest_Derive还有一个MyTest_Parts 类型的成员变量。现在MyTest_Derive构造的时候,是在父类MyTest_Base已构造完毕和MyTest_Parts类型的成员变量 m_component也已构造完毕之后,再抛出了一个异常,这种情况称为对象的部分构造。是的,这种情况很常见,对象总是由不断的继承或不断的聚合而 来,对象的构造过程实际上是这些所有的子对象按规定顺序的构造过程,其中这些过程中的任何一个子对象在构造时发生异常,对象都不能说自己完成了全部的构造 过程,因此这里就有一个棘手的问题,当发生对象的部分构造时,对象将析构吗?如果时,又将如何析构呢?

  (1) 对象的部分构造是很常见的,异常的发生点也完全是随机的,程序员要谨慎处理这种情况;

  (2) 当对象发生部分构造时,已经构造完毕的子对象将会逆序地被析构(即异常发生点前面的对象);而还没有开始构建的子对象将不会被构造了(即异常发生点后面的 对象),当然它也就没有析构过程了;还有正在构建的子对象和对象自己本身将停止继续构建(即出现异常的对象),并且它的析构是不会被执行的。

本文链接:http://izytravel.com/paochuyichang/642.html