第7集构造函数中抛出的异常

第7集构造函数中抛出的异常,第1张

第7集构造函数中抛出的异常,第2张

上一篇文章简单讨论了一下对象的成员函数抛出异常时的处理情况。本文中将继续讨论当在构造函数中抛出异常时,程序的执行情况又如何?这有点复杂呀!而且主人公阿愚还觉得这蛮有点意思!
构造函数中抛出的异常

  1、标准C++中定义构造函数是一个对象构建自己,分配所需资源的地方,一旦构造函数执行完毕,则表明这个对象已经诞生了,有自己的行为和内部的运行状态,之后还有对象的消亡过程(析构函数的执行)。可谁能保证对象的构造过程一定能成功呢?说不定系统当前的某个资源不够,导致对象不能完全构建好自己(人都有畸形儿,更何况别的呢?朋友们!是吧!),因此通过什么方法来表明对象的构造失败了呢?C++程序员朋友们知道,C++中的构造函数是没有返回值的,所以不少关于C++编程方面的书上得出结论:“因为构造函数没有返回值,所以通知对象的构造失败的方法那就是在构造函数中抛出异常”。主人公阿愚非常不同意这种说法,谁说的,便不信邪!虽然C++标准规定构造函数是没有返回值,可我们知道每个函数实际上都会有一个返回值的,这个值被保存在eax寄存器中,因此实际上是有办法通过编程来实现构造函数返回一个值给上层的对象创建者。当然即便是构造函数真的不能有返回值,我们也可以通过一个指针类型或引用类型的出参来获知对象的构造过程的状态。示例如下:
class MyTest_Base
{
public:
MyTest_Base (int& status)
{
//do other job
// 由于资源不够,对象构建失败
// 把status置0,通知对象的构建者
status = 0;
}
protected:
};
void main()
{
int status;
MyTest_Base obj1(status);
// 检查对象的构建是否成功
if(status ==0) cout << “对象构建失败” << endl;
}
  程序运行的结果是:
  对象构建失败
  是啊!上面我们不也得到了对象构造的成功与否的信息了吗?可大家有没有觉得这当中有点问题?主人公阿愚建议大家在此停留片刻,仔细想想它会有什么问题?OK!也许大家都知道了问题的所在,来验证一下吧!

class MyTest_Base
{
public:
MyTest_Base (int& status)
{
//do other job
// 由于资源不够,对象构建失败
// 把status置0,通知对象的构建者
status = 0;
}
virtual ~ MyTest_Base ()
{
cout << “销毁一个MyTest_Base类型的对象” << endl;
}

protected:
};
void main()
{
int status;
MyTest_Base obj1(status);
// 检查对象的构建是否成功
if(status ==0) cout << “对象构建失败” << endl;
}
  程序运行的结果是:
  对象构建失败
  销毁一个MyTest_Base类型的对象
  没错,对象的析构函数被运行了,这与C++标准中所规定的面向对象的一些特性是有冲突的。一个对象都没有完成自己的构造,又何来析构!好比一个夭折的畸形儿还没有出生,又何来死之言。因此这种方法是行不通的。那怎么办?那就是上面那个结论中的后一句话是对的,通知对象的构造失败的方法那就是在构造函数中抛出异常,但原因却不是由于构造函数没有返回值而造成的。恰恰相反,C++标准中规定构造函数没有返回值正是由于担心很容易与面向对象的一些特性相冲突,因此干脆来个规定,构造函数不能有返回值(主人公阿愚的个人理解,有不同意见的朋友欢迎讨论)。
   2、构造函数中抛出异常将导致对象的析构函数不被执行。哈哈^-^,阿愚很开心,瞧瞧!如果没有C++的异常处理机制鼎立支持,C++中的面向对象特性都无法真正实现起来,C++标准总不能规定所有的对象都必须成功构造吧!这也太理想化了,也许只有等到共产主义社会实现的那一天(CPU可以随便拿,内存可以随便拿,所有的资源都是你的!)才说不定有可能·····,所以说C++的异常处理和面向对象确实是谁也离不开谁。当然示例还是要看一下,如下:
class MyTest_Base
{
public:
MyTest_Base (string name = “”) : m_name(name)
{
throw std::exception(“在构造函数中抛出一个异常,测试!”);
cout << “构造一个MyTest_Base类型的对象,对象名为:”<}
virtual ~ MyTest_Base ()
{
cout << “销毁一个MyTest_Base类型的对象,对象名为:”<}
void Func() throw()
{
throw std::exception(“故意抛出一个异常,测试!”);
}
void Other() {}
protected:
string m_name;
};
void main()
{
try
{
// 对象构造时将会抛出异常
MyTest_Base obj1(“obj1”);
obj1.Func();
obj1.Other();
}
catch(std::exception e)
{
cout << e.what() << endl;
}
catch(...)
{
cout << “unknow exception”<< endl;
}
}
  程序的运行结果将会验证:“构造函数中抛出异常将导致对象的析构函数不被执行”

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » 第7集构造函数中抛出的异常

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情