學習C++:異常處理

      網友投稿 949 2025-03-31

      1.導致異常的原因

      異常可能是外部因素導致的,如系統沒有足夠的內存;也可能是應用程序內部因素導致的,如使用的指針包含無效值或除數為零。為向調用者指出錯誤,有些模塊引發異常。

      異常會打斷應用程序的正常流程。畢竟,如果沒有內存可用,應用程序就無法完成分配給它的任務。然而應用程序可處理這種異常:向用戶顯示一條友好的錯誤消息,采取必要的挽救措施并妥善地退出。

      2.使用try和catch捕獲異常

      要捕獲語句可能引發的異常,可將它們放在try塊中,并使用catch塊對try塊可能引發的異常進行處理,語法如下:

      void Func() { try { int* pNumber = new int; *pNumber = 999; delete pNumber; } catch(...) { cout<<"Exception in Func, quiting"<

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      (1)使用catch(…)處理所有異常

      成功分配內存時,默認形式的new返回一個指向該內存單元的有效指針,但失敗時引發異常。下面將演示如何捕獲使用new分配內存時可能引發的異常,并在計算機不能分配請求的內存時進行處理。

      #include using namespace std; int main() { cout<<"輸入要存儲的整數的個數:"; try { int Input = 0; cin>>Input; int* pRInts = new int [Input]; //自動分配內存空間 delete[] pRInts; } catch(...) //...捕獲所有類型的異常 { cout<<"Got to end, sorry!"<

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      在此程序中,如果鍵盤輸入的Input為一個負數,這顯然不符合要求。如果沒有異常處理,該程序將以討厭你的方式終止。但由于有異常處理程序,程序將顯示一條友好的消息:Got to end, sorry!結束程序。

      (2)捕獲特定類型的異常

      一般的異常的類型是已知的,為了查明導致異常的原因,執行更有針對性的清理工作,或者至少是向用戶顯示一條提示消息,這時就可以選擇捕獲這種類型的異常。

      其實上面(1)中的程序,當鍵盤輸入指定存儲的個數為負數時,將導致引發異常,而該異常類型為std::bad_alloc。

      下面程序將演示捕獲std::bad_alloc類型的異常:

      #include #include using namespace std; int main() { cout<<"輸入要存儲的整數的個數:"; try { int Input = 0; cin>>Input; int* pRInts =new int [Input]; delete[] pRInts; } catch(std::bad_alloc& exp) //捕獲類型為bad_alloc的異常,這種異常由new引發 { cout<<"Exception encountered: "<

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      學習C++:異常處理

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      3.使用throw引發特定類型的異常

      在上面演示的程序中,捕獲std::bad_alloc時,實際上是捕獲new引發的std::bad_alloc類對象。你也可以引發自己選擇的異常,為此只需要使用關鍵字throw。語法如下:

      void Func()

      {

      if(case_unwanted)

      throw Value;

      }

      當做除法運算時,若除數為0將導致程序異常。下面將演示如何使用throw引發這種自定義異常:

      #include using namespace std; double Divide(double Dividend, double Divisor) { if (Divisor == 0) throw "Divisor should not be zero!"; return (Dividend / Divisor); } int main() { cout << "Enter Dividend: "; double Dividend = 0; cin >> Dividend; cout << "Enter Divisor: "; double Divisor = 0; cin >> Divisor; try { cout << "Dividend/Divisor=" << Divide(Dividend, Divisor); } catch(const char* exp) //捕獲類型為char*的異常,于是可調用函數Divide()中可能引發的異常throw { cout << "Exception: " << exp << endl; cout << "Sorry, can't continue!" << endl; } return 0; }

      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

      注意:上述代碼沒有將整個main()都放在try{}中,而只在其中包含可能引發異常的代碼。提倡這種做法,因為異常處理也可能降低代碼的執行性能。

      4.std::exception類

      捕獲std::bad_alllocl類型異常時,實際上是捕獲new引發的std::bad_alloc對象。std::bad_alloc繼承了C++標準類std::exception,而使用exception類時,需要添加頭文件:#include

      從std::exception派生出來的幾個重要的異常類:

      bad_alloc: 使用new請求內存失敗時引發

      bad_cast: 試圖使用dynamic_cast轉換錯誤類型時引發

      ios_base::failure: 由iostream庫中的函數和方法引發

      std::exception是異常基類,定義了虛函數what(),用來描述導致異常的原因。

      因為std::exception是眾多異常類型的基類,所以所有將std::exception作為基類的異常,均可使用catch(const exception&)捕獲:

      void Func() { try { // code made exception safe } catch(const std::exception& exp) { cout<<"導致異常的原因是:"<

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      從std::exception派生出自定義異常類

      讓自定義異常繼承std::exception的好處在于,現有的異常處理程序catch(const std::exception)不但能捕獲bad_alloc、bad_cast等異常,還能捕獲自定義異常,因為它們的基類都是exception。

      下面將演示繼承std::exception的CustomException類:

      #include #include #include using namespace std; class CustomException : public std::exception { string Reason; public: CustomException(const char* why) :Reason(why) {} virtual const char* what() const throw() { return Reason.c_str(); } }; double Divide(double Dividend, double Divisor) { if (Divisor == 0) throw CustomException("CustomException: Divisor should not be zero!"); return (Dividend / Divisor); } int main() { double Dividend = 0, Divisor = 0; cout << "Enter Dividend: "; cin >> Dividend; cout << "Enter Divisor: "; cin >> Divisor; try { cout << "Dividend/Divisor=" << Divide(Dividend, Divisor); } catch (exception& exp) //不但處理異常CustomException,還處理bad_alloc等其他以exception為基類的異常 { cout << "導致異常的原因:"<

      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

      C++

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:注冊生產型制造企業流程(注冊生產型制造企業流程)
      下一篇:wps文字打開兩個文檔進行比較方法
      相關文章
      亚洲一区二区成人| 亚洲va中文字幕无码久久| 精品亚洲成a人片在线观看少妇| 亚洲午夜久久久久久噜噜噜| 国产精品亚洲а∨天堂2021| 亚洲AV色无码乱码在线观看| 亚洲一区二区三区高清在线观看| 亚洲中字慕日产2021| 亚洲国产成人精品电影| 亚洲精品在线视频观看| 久久久久亚洲AV无码麻豆| 亚洲人成电影亚洲人成9999网| 亚洲国产人成网站在线电影动漫| 亚洲AV日韩AV天堂一区二区三区| 久久精品国产亚洲AV麻豆王友容| 亚洲av综合av一区| 亚洲Aⅴ无码专区在线观看q| 亚洲国产一区二区a毛片| 亚洲一区综合在线播放| 精品日韩亚洲AV无码一区二区三区| 麻豆亚洲av熟女国产一区二| 亚洲黄色网址大全| 亚洲一级高清在线中文字幕| 久久精品亚洲AV久久久无码| 亚洲国产熟亚洲女视频| 亚洲国产精品18久久久久久| 无码一区二区三区亚洲人妻| 亚洲中文无韩国r级电影| 国产aⅴ无码专区亚洲av麻豆 | 亚洲a级在线观看| 日韩亚洲国产综合高清| 国产精品亚洲专区无码WEB| 亚洲AV中文无码乱人伦| 亚洲一区二区三区香蕉| 久久久久亚洲精品美女| 亚洲日本在线观看网址| 香蕉大伊亚洲人在线观看| 看亚洲a级一级毛片| 久久久无码精品亚洲日韩软件 | 亚洲高清有码中文字| 亚洲成av人片天堂网无码】|