时间:2021-05-02
异常处理基本思想
C++的异常处理的基本思想大致可以概括为传统错误处理机制、通过函数返回值来处理错误。
1)C++的异常处理机制使得异常的引发和异常的处理不必在同一个函数中,这样底层的函数可以着重解决具体问题,而不必过多的考虑异常的处理。上层调用者可以再适当的位置设计对不同类型异常的处理。
2)异常是专门针对抽象编程中的一系列错误处理的,C++中不能借助函数机制,因为栈结构的本质是先进后出,依次访问,无法进行跳跃,但错误处理的特征却是遇到错误信息就想要转到若干级之上进行重新尝试,如图
3)异常超脱于函数机制,决定了其对函数的跨越式回跳。
4)异常跨越函数
异常基本语法
1) 若有异常则通过throw操作创建一个异常对象并抛掷。
2) 将可能抛出异常的程序段嵌在try块之中。控制通过正常的顺序执行到达try语句,然后执行try块内的保护段。
3) 如果在保护段执行期间没有引起异常,那么跟在try块后的catch子句就不执行。程序从try块后跟随的最后一个catch子句后面的语句继续执行下去。
4) catch子句按其在try块后出现的顺序被检查。匹配的catch子句将捕获并处理异常(或继续抛掷异常)。
5) 如果匹配的处理器未找到,则运行函数terminate将被自动调用,其缺省功能是调用abort终止程序。
6)处理不了的异常,可以在catch的最后一个分支,使用throw语法,向上扔
7)异常机制与函数机制互不干涉,但捕捉的方式是基于类型匹配。捕捉相当于函数返回类型的匹配,而不是函数参数的匹配,所以捕捉不用考虑一个抛掷中的多种数据类型匹配问题。
catch代码块必须出现在try后,并且在try块后可以出现多个catch代码块,以捕捉各种不同类型的抛掷。
异常机制是基于这样的原理:程序运行实质上是数据实体在做一些操作,因此发生异常现象的地方,一定是某个实体出了差错,该实体所对应的数据类型便作为抛掷和捕捉的依据。
8)异常捕捉严格按照类型匹配
异常捕捉的类型匹配之苛刻程度可以和模板的类型匹配媲美,它不允许相容类型的隐式转换,比如,抛掷char类型用int型就捕捉不到.例如下列代码不会输出“int exception.”,从而也不会输出“That's ok.” 因为出现异常后提示退出
栈解旋(unwinding)
异常被抛出后,从进入try块起,到异常被抛掷前,这期间在栈上的构造的所有对象,都会被自动析构。析构的顺序与构造的顺序相反。这一过程称为栈的解旋(unwinding)。
异常接口声明
1)为了加强程序的可读性,可以在函数声明中列出可能抛出的所有异常类型,例如:
void func() throw (A, B, C , D); //这个函数func()能够且只能抛出类型A B C D及其子类型的异常。
2)如果在函数声明中没有包含异常接口声明,则次函数可以抛掷任何类型的异常,例如:
void func();
3)一个不抛掷任何类型异常的函数可以声明为:
void func() throw();
4) 如果一个函数抛出了它的异常接口声明所不允许抛出的异常,unexpected函数会被调用,该函数默认行为调用terminate函数中止程序。
传统处理错误
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 #include <iostream> #include <cstdio> using namespace std; // 传统的错误处理机制 int myStrcpy(char *to, char *from) { if (from == NULL) { return 1; } if (to == NULL) { return 2; } // copy时的场景检查 if (*from == 'a') { return 3; // copy时错误 } while (*from != '\0') { *to = *from; to++; from++; } *to = '\0'; return 0; } int main() { int ret = 0; char buf1[] = "zbcdefg"; char buf2[1024] = { 0 }; ret = myStrcpy(buf2, buf1); if (ret != 0) { switch (ret) { case 1: cout << "源buf出错!\n"; break; case 2: cout << "目的buf出错!\n"; break; case 3: cout << "copy过程出错!\n"; break; default: cout << "未知错误!\n"; break; } } cout << "buf2:\n" << buf2; cout << endl; return 0; }throw char*
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include <iostream> #include <cstdio> using namespace std; // throw char * void myStrcpy(char *to, char *from) { if (from == NULL) { throw "源buf出错"; } if (to == NULL) { throw "目的buf出错"; } // copy时的场景检查 if (*from == 'a') { throw "copy过程出错"; // copy时错误 } while (*from != '\0') { *to = *from; to++; from++; } *to = '\0'; return; } int main() { int ret = 0; char buf1[] = "abcdefg"; char buf2[1024] = { 0 }; try { myStrcpy(buf2, buf1); } catch (int e) // e可以写可以不写 { cout << e << "int类型异常" << endl; } catch (char *e) { cout << "char* 类型异常" << endl; } catch (...) { }; cout << endl; return 0; }throw 类对象
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <iostream> #include <cstdio> using namespace std; class BadSrcType {}; class BadDestType {}; class BadProcessType { public: BadProcessType() { cout << "BadProcessType构造函数do \n"; } BadProcessType(const BadProcessType &obj) { cout << "BadProcessType copy构造函数do \n"; } ~BadProcessType() { cout << "BadProcessType析构函数do \n"; } };
throw 类对象、类型异常
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
Javathrow:异常的抛出程序可以用throw语句抛出明确的异常。Throw语句的通常形式如下:throwThrowableInstance;这里,Thro
若要在C++中实现异常处理,你可以使用try、throw和catch表达式。首先,使用try块将可能引发异常的一个或多个语句封闭起来。throw表达式发出信号,
使用异常PHP5增加了类似其他语言的异常处理模块。在PHP代码中所产生的异常可被throw语句抛出并被catch语句捕获。需要进行异常处理的代码都必须放入到tr
1析构函数中是否可以抛出异常首先我们看一个常见的问题,析构函数中是否可以抛出异常。答案是C++标准指明析构函数不能、也不应该抛出异常!C++异常处理模型是为C+
PHP5添加了类似于其它语言的异常处理模块。在PHP代码中所产生的异常可被throw语句抛出并被catch语句捕获。(注:一定要先抛才能获取)需要进行异常处理的