異常型別變數的生命週期
阿新 • • 發佈:2020-10-09
傳統的錯誤處理機制:
#include<iostream> using namespace std; //傳統的處理機制 int my_strcopy(char* from, char* to) { if (from == NULL) return 1; if (to == NULL) return 2; //拷貝場景檢查 if (*from == 'a') return 3; while (*from != '\0') { *to = *from; to ++;from ++; } *to = '\0'; return 0; } int main() { int ret = 0; char buf1[] = "abcdefg"; char buf2[1024] = { 0 }; ret = my_strcopy(buf1, buf2); if (ret != 0) { switch (ret) { case 1: cout << "源buf出錯!" << endl; break; case 2: cout << "目的buf出錯!" << endl; case 3: cout << "拷貝過程出錯!" << endl; default: cout << "未知錯誤" << endl; break; } } cout << "buf2 = " << buf2 << endl; system("pause"); return 0; }
用異常解決:
#include<iostream> using namespace std; //傳統的處理機制 //throw int 型別異常 void my_strcopy2(char* from, char* to) { if (from == NULL) throw 1; if (to == NULL) throw 2; //拷貝場景檢查 if (*from == 'a') throw 3; while (*from != '\0') { *to = *from; to ++; from ++; } *to = '\0'; } //throw char 型別異常 void my_strcopy1(char* from, char* to) { if (from == NULL) throw "源buf出錯"; if (to == NULL) throw "目的buf出錯"; //拷貝場景檢查 if (*from == 'a') throw "copy時出錯"; while (*from != '\0') { *to = *from; to++; from++; } *to = '\0'; } class BadSrcType{}; class BadDestType{}; class BadProcessType{}; //throw 類物件型別異常 void my_strcopy3(char* from, char* to) { if (from == NULL) throw BadSrcType(); //會不會產生匿名物件 if (to == NULL) throw BadDestType(); //拷貝場景檢查 if (*from == 'a') throw BadProcessType(); while (*from != '\0') { *to = *from; to++; from++; } *to = '\0'; } int main() { int ret = 0; char buf1[] = "abcdefg"; char buf2[1024] = { 0 }; try { my_strcopy3(buf1, buf2); } catch (int e )//變數名可以寫可以不寫 { cout << "int型別異常" << endl; } catch (char *e) { cout << e << "char*型別異常" << endl; } //--- catch (BadSrcType e)//是把匿名物件拷貝給e,還是e直接就是匿名物件 { cout << "BadSrcType型別異常" << endl; } catch (BadDestType e) { cout << "BadDestType型別異常" << endl; } catch (BadProcessType e) { cout << "BadProcessType型別異常" << endl; } //-- catch (...) { cout << "未知異常 " << endl; } system("pause"); return 0; }
接下來解決程式碼中提出的問題:
catch (BadSrcType e)//是把匿名物件拷貝給e,還是e直接就是匿名物件
先新增完類的定義:
class BadProcessType { public: BadProcessType() { cout << "BadProcessType建構函式do \n"; } BadProcessType(const BadProcessType& obj) { cout << "BadProcessType拷貝建構函式do \n"; } ~BadProcessType() { cout << "BadProcessType解構函式do \n"; } };
結論1:如果 接受異常的時候,使用一個異常變數,則拷貝構造異常變數
接下來測試引用:
catch (BadProcessType &e) { cout << "BadProcessType型別異常" << endl; }
沒有拷貝新的變數
結論2:如果使用引用,會使用throw的那個物件
下面測試指標:
catch (BadProcessType &e) { cout << "BadProcessType型別異常" << endl; } catch (BadProcessType* e) { cout << "BadProcessType型別異常" << endl; }
結論3:指標可以和引用和元素寫在一塊,但是元素和引用不能寫在一塊
此時丟擲異常時應該丟擲地址:
if (*from == 'b') throw& (BadProcessType());
此時因為解構函式已經完成,指標變成了野指標。
所以指標應當這樣丟擲:
if (*from == 'c') throw new BadProcessType;
catch (BadProcessType* e) { cout << "BadProcessType地址型別異常" << endl; delete e; }
略煩,所以最好選擇引用來抓取異常。所有操作都自動處理。