STL5-异常
異??梢钥绾瘮?/p>
異常必須處理
1、
#include<iostream> using namespace std; //c++異常機制 跨函數 //c++異常必須處理 不能留,否則報錯 int divided(int x, int y) {if (y == 0)throw y; //拋異常return (x / y); } void test01() {int x = 10, y = 0;//試著去捕獲異常try{divided(x, y);}catch (int y) //異常是根據類型進行匹配{cout << "除數為" << y <<"!"<< endl;} }void CallDivide(int x, int y) {divided(x, y); } //如果異常拋到頂層,還沒有處理這個時候程序后掛掉terminal() //a調用b,b調用c,c調用d函數 a-->b-->c-->d //d拋出異常,c沒有處理,則繼續給b,b還沒有處理給a,則異常給a,a處理(catch)即可。若a還不處理,則報錯,程序掛掉 void test02() {try{CallDivide(1, 0);}catch (int e){cout << "除數為" << e << endl;} } int main() {test01();cout << "------------------" << endl;test02(); }2、棧解旋
#include<iostream> using namespace std;class person { public:person(){cout << "對象構建" << endl;}~person(){cout << "對象析構" << endl;}};int divide(int x, int y) {person p1, p2;if (y == 0)throw y;return x / y; } //棧解旋:try catch中調用函數發生異常時,函數內的局部變量會被析構掉 void test01() {try {divide(10, 0);}catch (int e){cout << "異常捕獲!" << endl;} }int main() {test01();return 0; }3、異常接口的聲明
#include<iostream> using namespace std; //這個函數只能拋出int,float,char三種類型異常,拋出其他報錯 void func() throw(int, float, char) {throw "abc"; } //不能拋出任何類型異常 void func02() throw() {throw - 1; } //拋出任何類型異常 void func03() {throw - 2; } int main() {try {func();}catch (char* str){cout << str << endl;}catch (int e){cout << "異常!" << endl;}catch (...) //...代表所有異常類型{cout << "捕獲所有未知類型異常" << endl;} }?
4、異常類型
#include<iostream> using namespace std;void func01(){throw 1; //拋出int類型異常 } void func02() {throw "exception"; //拋出char*類型異常 } class MyException { public:MyException(char* str) {error = new char[strlen(str) + 1];strcpy(error, str);}void what() {cout << error << endl;}MyException(const MyException& ex){ //拷貝構造this->error = new char[strlen(ex.error) + 1];strcpy(this->error, ex.error);}MyException& operator=(const MyException& ex) { //等于構造if (this->error != NULL){delete[] this->error;this->error = NULL;}this->error = new char[strlen(ex.error) + 1];strcpy(this->error, ex.error);}MyException(){if (error != NULL){delete[] error;}} public:char* error; }; void func03() {throw MyException("我剛寫的異常!"); } void test01(){try {func01();}catch (int e) {cout << "異常捕獲!" << endl;} //----------------------------------------try {func02();}catch (char* e) {cout << "異常捕獲!" << endl;} //-----------------------------------------try {func03();}catch (MyException e) {e.what();} }int main() {MyException e1=MyException("dd"); //拷貝構造MyException e2 = e1; //等于構造test01();return 0; }運行結果:?
5、異常生命周期
#include<iostream> using namespace std;class MyException { public:MyException() {cout << "構造函數" << endl;}MyException(const MyException& ex) { //拷貝構造cout << "拷貝構造函數" << endl;}~MyException() {cout << "析構函數" << endl;}}; void func() {//throw MyException(); //創建匿名對象,調用構造函數//throw &(MyException()); //創建匿名對象,調用構造函數throw new MyException(); } void test01() {//普通類型元素 引用 指針//普通類型元素 catch處理完后就析構//引用的話 不用調用拷貝構造 catch處理完后就析構//指針的話,需要new一個異常,否則在捕捉異常前就已經析構try {func();}//catch (MyException e) { //用MyException元素接,相當于將上面的MyException()拷貝一份傳給e,調用拷貝構造// cout << "異常捕獲" << endl;//}//catch (MyException& e) { //用MyException元素接,相當于將上面的MyException()拷貝一份傳給e,調用拷貝構造// cout << "異常捕獲" << endl;//}catch (MyException* e) { //用MyException元素接,相當于將上面的MyException()拷貝一份傳給e,調用拷貝構造cout << "異常捕獲" << endl;delete e;} }int main() {test01();return 0; }運行結果:?
6、c++異常庫舉例
#include<iostream> #include<stdexcept> using namespace std;class Person { public:Person() {mAge = 0;}void setAge(int age){if (age < 0 || age>100) {throw out_of_range("年齡在0-100之間!");}this->mAge = age;} public:int mAge; }; void test01(){Person p;try {p.setAge(1000);}catch (out_of_range e) {cout << e.what() << endl;}catch (exception e) {cout << e.what() << endl;} }class MyOutOfRange : public exception { public:MyOutOfRange(char* error) {pError = new char[strlen(error) + 1];strcpy(pError, error);}virtual char const* what() const {return pError;}MyOutOfRange() {if (pError != NULL) {delete[] pError;}} public:char* pError; }; void func02() {throw MyOutOfRange("我自己拋出的異常"); } void test02() {try {func02();}catch (exception& e) {cout << e.what() << endl;} } int main() {test01();test02();return 0; }運行結果:?
7、繼承在異常中的應用
#include<iostream> using namespace std;//異常基類 class BaseMyException { public:virtual void what()=0;virtual ~BaseMyException() {}; }; class TargetSpaceNullException :public BaseMyException { public:virtual void what() {cout << "目標空間為空!" << endl;}~TargetSpaceNullException(){} }; class SourceSpaceNullException :public BaseMyException { public:virtual void what() {cout << "源空間為空" << endl;}~SourceSpaceNullException() {} };void copy_str(char* target, char* source){if (target == NULL){//cout << "目標空間為空" << endl;throw TargetSpaceNullException();return;}if (source == NULL) {throw SourceSpaceNullException();//cout << "源空間為空" << endl;return;}int len = strlen(source)+1;while (*source != '\0') {*target = *source;source++;target++;} }int main() {char* source = "abcdefg";char buf[1024] = { 0 };cout << "copy" << endl;try {copy_str(NULL, source);}catch (BaseMyException& e) {e.what();}cout << buf << endl;return 0; }?
?
總結
- 上一篇: 电脑安装命令记录
- 下一篇: Leedcode4-sort listn