品牌高端网站设计,颇有名气的网站建设专家,自己做网站导航页,网站的维护工作内容转自#xff1a;http://blog.csdn.net/makenothing/article/details/43273137 例1#xff1a;自定义一个继承自excepton的异常类myException C标准中#xff0c;定义在stdexcept中的任何异常类都派生自exception Class#xff0c;本例也只是简单地由exception继承http://blog.csdn.net/makenothing/article/details/43273137 例1自定义一个继承自excepton的异常类myException C标准中定义在stdexcept中的任何异常类都派生自exception Class本例也只是简单地由exception继承在try段抛出一个异常并捕捉。代码如下 [cpp] view plaincopy print? /* test.cpp version:1.0 decript:define a exception class named myException derived from base class exception which is declared in exception created:2011-08-14 author: btwsmile --*/ #includeexception #includeiostream using namespace std; //customized exception class myException class myException:public exception { public: myException():exception(ERROR! Dont divide a number by integer zero.\n) { } }; //entry of the application int main() { int x100,y0; try { if(y0) throw myException(); else coutx/y; } catch(myException me) { coutme.what(); } system(pause); return 0; } 结果如下 ERROR! Dont divide a number by integer zero. 请按任意键继续. . . 显然异常被捕捉到了。此处需要说明的是VC对异常处理类exception进行了扩展本例之所以能够使用exception(ERROR!....)的初始化方法正出于这样的原因C标准是不允许这样做的。 与此同时VC又没有遵循标准有力地支持terminate和unexpected它只保留了语法却在编译运行时不提供支持。为了结合terminate和unexpected更加深入了解C的异常处理下面的例子采用Dev cpp IDE实现。 例2依照C标准实现自定义异常类myException并将throw语句封装到函数check()中 涉及到的更改正如标题所述1重写基类的what()函数返回错误信息2将throw myException()封装到check()函数中(3)允许check()函数抛出myException类型的异常。代码如下 [cpp] view plaincopy print? /* test.cpp version:1.1 decript:define a exception class named myException according to C standard, derived from base class exception which is declared in exception !also,encapusulate throw into a function created:2011-08-14 author: btwsmile --*/ #includeexception #includeiostream using namespace std; //customized exception class myException class myException:public exception { public: const char* what()const throw()//#1 { return ERROR! Dont divide a number by integer zero.\n; } }; void check(int y) throw(myException)//#2 { if(y0) throw myException(); } //entry of the application int main() { int x100,y0; try { check(y); coutx/y; } catch(myException me) { coutme.what(); } system(pause); return 0; } 结果与例1完全相同。需说明的是紧跟check()后的throw列表表明允许该函数抛出的异常类型。这里不得不产生疑问如果抛出了一个不被允许的异常类型将怎样 例3抛出unexpected异常 check函数体之后的throw列表规定了允许抛出的异常类型一旦违背就将触发unexpected。可以把unexpected看作系统自动调用的CALLBACK函数不同的是也可以手工触发它的执行。本例的情况属于前者。代码如下 [cpp] view plaincopy print? /* test.cpp version:1.3 decript:define an unexpected excption handler, set it by using set_unexpected, modify the throw list of function check created:2011-08-14 author: btwsmile --*/ #includeexception #includeiostream using namespace std; //customized exception class myException class myException:public exception { public: const char* what()const throw() { return ERROR! Dont divide a number by integer zero.\n; } }; void check(int y) throw()//#1 only int-type exception is permitted { if(y0) throw myException(); } void myUnexpected() { coutUnexpected exception caught!\n; system(pause); exit(-1); } //entry of the application int main() { unexpected_handler oldHandlerset_unexpected(myUnexpected); int x100,y0; try { check(y); coutx/y; } catch(myException me) { coutme.what(); } system(pause); return 0; } 结果如下 Unexpected exception caught! 请按任意键继续. . . check函数的throw列表为空即不允许抛出任何类型的异常然而实际上当异常发生时系统不能等闲视之它将调用unexpected处理方法。所以限定一个函数throw列表为空是值得程序员警醒的事需要特别留意。如果将#1处的代码修改为throw(int)等也能得到相同的结果。所谓unexpected异常说白了就是函数体允许抛出异常类型范围之外的异常。如果check函数后面根本没有throw则表示函数任何类型的异常都被允许。 例4抛出函数体允许的异常但没被捕捉到的情况 思考这样一个问题如果函数check的throw列表中有异常类型myException而且在y0时它的确抛出myException类型的异常但是没有被catch到这时会发生什么 在正式回答这个问题之前先讨论“没被catch到”的意思。比如修改例3的代码如下##为修改之处 [cpp] view plaincopy print? /* test.cpp version:1.4.1 decript: how to understand exception not caucht? created:2011-08-14 author: btwsmile --*/ #includeexception #includeiostream using namespace std; //customized exception class myException class myException:public exception { public: const char* what()const throw() { return ERROR! Dont divide a number by integer zero.\n; } }; void check(int y) //any type of exception is permitted { if(y0) throw myException(); } void myUnexpected() { coutUnexpected exception caught!\n; system(pause); exit(-1); } //entry of the application int main() { unexpected_handler oldHandlerset_unexpected(myUnexpected); int x100,y0; try { check(y); coutx/y; } catch(int e) //##1 no catch sentence matches the throw type { couteendl; } /* ##2 if add this part, any type whichs not handler before will be caught catch(...) { coutUnkown exception caught!\n; } */ system(pause); return 0; } 编译运行程序将会出错因为check函数抛出的myException异常没有被处理。在缺省情况下一旦出现抛出异常没被处理的问题系统将自动调用abort()函数终止程序允许在控制台将会看到这样的提示 This application has requested the Runtime to terminate it in an unusual way.Please contact the applications support team for more information. 不过可以增加##2部分的代码catch(...)表示捕捉任何类型的异常。 注意check函数不被允许的异常类型并不会进入到catch语句的判断中来因此catch(...)对unexpected exception没有作用。 仍然考虑没有##2部分的情况。正如前面所述系统将自动调用abort()函数终止程序。实际上它触发的是terminate类似于unexpected仍然可以自定义terminate的处理方法。甚至terminate语法上跟unexpected都十分近似。修改代码为 [cpp] view plaincopy print? /* test.cpp version:1.4.2 decript: how to understand exception not caucht? created:2011-08-14 author: btwsmile --*/ #includeexception #includeiostream using namespace std; //customized exception class myException class myException:public exception { public: const char* what()const throw() { return ERROR! Dont divide a number by integer zero.\n; } }; void check(int y) //any type of exception is permitted { if(y0) throw myException(); } void myUnexpected() { coutUnexpected exception caught!\n; system(pause); exit(-1); } void myTerminate() //##1 set it be the terminate handler { coutUnhandler exception!\n; system(pause); exit(-1); } //entry of the application int main() { unexpected_handler oldHandlerset_unexpected(myUnexpected); terminate_handler preHandlerset_terminate(myTerminate); int x100,y0; try { check(y); coutx/y; } catch(int e) //no catch sentence matches the throw type { couteendl; } system(pause); return 0; } 结果如下 Unhandler exception! 请按任意键继续. . . 结论C为异常处理提供了友好的支持。 用户可以自定义异常类型异常类型并不受到限制可以是内建数据类型如int,double等也可以是自定义的类也可以从C某个异常类继承下来。例1采用了派生自exception的方法。 除此之外在定义函数时可以显式指定函数体抛出的异常类型。隐式情况下缺省允许函数抛出任何类型的异常。有可以增加throw语句对异常类型加以限制。特别的是throw()表示不允许函数抛出任何类型的异常。如果违反了throw列表规定的异常类型系统将调用unexpected hanlder进行处理可以自定义unexpected异常处理方法。例2和例3对它们进行了说明。 如果对于函数体throw列表合法的异常被抛出但是却没有被程序捕捉处理系统将调用terminate handler进行处理。缺省情况下只是简单调用abort()函数终止程序同样可以自定义terminate处理方法。例4对它进行了说明。