C++中异常处理的基本思想及throw语句抛出异常的使用
异常处理基本思想 1)C++的异常处理机制使得异常的引发和异常的处理不必在同一个函数中,这样底层的函数可以着重解决具体问题,而不必过多的考虑异常的处理。上层调用者可以再适当的位置设计对不同类型异常的处理。 3)异常超脱于函数机制,决定了其对函数的跨越式回跳。 异常基本语法 1) 若有异常则通过throw操作创建一个异常对象并抛掷。 int main(){ try{ throw ‘H'; } catch (int){ cout << "int exception.n"; } cout << "That's ok.n"; return 0; } 栈解旋(unwinding) #include <iostream> #include <cstdio> using namespace std; class MyException {}; class Test { public: Test(int a = 0,int b = 0) { this->a = a; this->b = b; cout << "Test 构造函数执行" << "a:" << a << " b: " << b << endl; } void printT() { cout << "a:" << a << " b: " << b << endl; } ~Test() { cout << "Test 析构函数执行" << "a:" << a << " b: " << b << endl; } private: int a; int b; }; void myFunc() throw (MyException) { Test t1; Test t2; cout << "定义了两个栈变量,异常抛出后测试栈变量的如何被析构" << endl; throw MyException(); } int main() { //异常被抛出后,从进入try块起,到异常被抛掷前,这期间在栈上的构造的所有对象, //都会被自动析构。析构的顺序与构造的顺序相反。 //这一过程称为栈的解旋(unwinding) try { myFunc(); } //catch(MyException &e) //这里不能访问异常对象 catch (MyException) //这里不能访问异常对象 { cout << "接收到MyException类型异常" << endl; } catch (...) { cout << "未知类型异常" << endl; } return 0; } 异常接口声明 传统处理错误 #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 != ' ') { *to = *from; to++; from++; } *to = ' '; 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* #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 != ' ') { *to = *from; to++; from++; } *to = ' '; 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 类对象 #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"; } }; void my_strcpy3(char *to,char *from) { if (from == NULL) { throw BadSrcType(); } if (to == NULL) { throw BadDestType(); } //copy是的 场景检查 if (*from == 'a') { printf("开始 BadProcessType类型异常 n"); throw BadProcessType(); //会不会产生一个匿名对象? } if (*from == 'b') { throw &(BadProcessType()); //会不会产生一个匿名对象? } if (*from == 'c') { throw new BadProcessType; //会不会产生一个匿名对象? } while (*from != ' ') { *to = *from; to++; from++; } *to = ' '; } int main() { int ret = 0; char buf1[] = "cbbcdefg"; char buf2[1024] = { 0 }; try { //my_strcpy1(buf2,buf1); //my_strcpy2(buf2,buf1); my_strcpy3(buf2,buf1); } catch (int e) //e可以写 也可以不写 { cout << e << " int类型异常" << endl; } catch (char *e) { cout << e << " char* 类型异常" << endl; } //--- catch (BadSrcType e) { cout << " BadSrcType 类型异常" << endl; } catch (BadDestType e) { cout << " BadDestType 类型异常" << endl; } //结论1: 如果 接受异常的时候 使用一个异常变量,则copy构造异常变量. /* catch( BadProcessType e) //是把匿名对象copy给e 还是e还是那个匿名对象 { cout << " BadProcessType 类型异常" << endl; } */ /*结论2: 使用引用的话 会使用throw时候的那个对象 catch( BadProcessType &e) //是把匿名对象copy给e 还是e还是那个匿名对象 { cout << " BadProcessType 类型异常" << endl; } */ //结论3: 指针可以和引用/元素写在一块 但是引用和元素不能写在一块 catch (BadProcessType *e) //是把匿名对象copy给e 还是e还是那个匿名对象 { cout << " BadProcessType 类型异常" << endl; delete e; } //结论4: 类对象时,使用引用比较合适 // -- catch (...) { cout << "未知 类型异常" << endl; } return 0; }
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |