C++ 異常說明/規範

來源:互聯網
上載者:User

1. 概念

 

異常說明/規範(exception specification)指定, 如果函數拋出異常, 被拋出的異常將是包含在該說明中的一種, 或者是從列出的異常中派生的類型.

 

2. 定義

異常說明跟在函數形參表之後. 一個異常說明在關鍵字throw之後跟著一個(可能為空白的)由圓括弧括起來的異常類型列表. 如:

void foo(int) throw (std::logic_error, std::runtime_error);

這個聲明指出, foo是接受int值的函數, 返回void. 如果foo拋出一個異常, 該異常將是std::logic_error或std::runtime_error對象, 或者由std::logic_error或std::runtime_error派生的類型的異常.

 

3. 說明

  • 編譯時間, 編譯器不能也不會試圖驗證異常說明;
  • 空說明列表指出函數不拋出任何異常;
  • 如果一個函式宣告沒有指定異常說明, 則該函數可以拋出任意類型的異常;
  • 異常說明是函數介面的一部分, 函數定義以及該函數的任意聲明必須具有相同的異常說明;
  • 異常說明不能用於函數重載;
  • 在const成員函式宣告中, 異常說明跟在const限定符之後;
  • 如果函數拋出了沒有在其異常說明中列出的異常, 就調用標準庫函數unexpected. 預設情況下, unexpected函數調用terminate函數, terminate函數一般會終止程式;
  • 異常說明/規範中不僅要包含函數本身引發的異常, 還應該包含該函數調用的其它函數引發的異常, 以此類推;
  • 引發異常時, 編譯器總是建立一個臨時拷貝, 即使catch塊中指定的是引用(這裡指定引用的目的並不是避免建立拷貝以提高效率, 而是: 基類引用可以執行衍生類別對象.). 如: 
    class problem {...};<br />...<br />void super() throw (problem)<br />{<br /> ...<br /> if (oh_no)<br /> {<br /> problem oops; // construct object<br /> throw oops; // throw it<br /> }<br /> ...<br />}<br />...<br />try<br />{<br /> super();<br />}<br />catch (problem& p)<br />{<br /> // statements<br />}<br />// 說明: p將指向oops的拷貝而不是oops本身. 這是件好事, 因為函數super()執行完畢後, oops將不複存在. 不過這裡可能更簡單:<br />// throw problem();  

4. 代碼

// usr_excep.h -- exception classes for hmean(), gmean()</p><p>#include <iostream> </p><p>class bad_hmean<br />{<br />private:<br /> double v1;<br /> double v2;<br />public:<br /> bad_hmean(double a = 0, double b = 0) : v1(a), v2(b){}<br /> void mesg();<br />};</p><p>inline void bad_hmean::mesg()<br />{<br /> std::cout << "hmean(" << v1 << ", " << v2 <<"): "<br /> << "invalid arguments: a = -b/n";<br />}</p><p>class bad_gmean<br />{<br />public:<br /> double v1;<br /> double v2;<br /> bad_gmean(double a = 0, double b = 0) : v1(a), v2(b){}<br /> const char * mesg();<br />};</p><p>inline const char * bad_gmean::mesg()<br />{<br /> return "gmean() arguments should be >= 0/n";<br />}

 

//foo.cpp -- unwinding the stack</p><p>#include <iostream><br />#include <cmath> // or math.h, unix users may need -lm flag<br />#include <cstring><br />#include "usr_excep.h"</p><p>class demo<br />{<br />private:<br /> char word[40];<br />public:<br /> demo (const char * str)<br /> {<br /> std::strcpy(word, str);<br /> std::cout << "demo " << word << " created/n";<br /> }<br /> ~demo()<br /> {<br /> std::cout << "demo " << word << " destroyed/n";<br /> }<br /> void show() const<br /> {<br /> std::cout << "demo " << word << " lives!/n";<br /> }<br />}; </p><p>// function prototypes<br />double hmean(double a, double b) throw(bad_hmean);<br />double gmean(double a, double b) throw(bad_gmean);<br />double means(double a, double b) throw(bad_hmean, bad_gmean);</p><p>int main()<br />{<br /> using std::cout;<br /> using std::cin;<br /> using std::endl;</p><p> double x, y, z;<br /> demo d1("found in main()");<br /> cout << "Enter two numbers: ";<br /> while (cin >> x >> y)<br /> {<br /> try<br /> { // start of try block<br /> z = means(x,y);<br /> cout << "The mean mean of " << x << " and " << y<br /> << " is " << z << endl;<br /> cout << "Enter next pair: ";<br /> } // end of try block<br /> catch (bad_hmean & bg) // start of catch block<br /> {<br /> bg.mesg();<br /> cout << "Try again./n";<br /> continue;<br /> }<br /> catch (bad_gmean & hg)<br /> {<br /> cout << hg.mesg();<br /> cout << "Values used: " << hg.v1 << ", "<br /> << hg.v2 << endl;<br /> cout << "Sorry, you don't get to play any more./n";<br /> break;<br /> } // end of catch block<br /> }<br /> d1.show();<br /> cout << "Bye!/n";</p><p> return 0;<br />}</p><p>double hmean(double a, double b) throw(bad_hmean)<br />{<br /> if (a == -b)<br /> {<br /> throw bad_hmean(a,b);<br /> }</p><p> return 2.0 * a * b / (a + b);<br />}</p><p>double gmean(double a, double b) throw(bad_gmean)<br />{<br /> if (a < 0 || b < 0)<br /> {<br /> throw bad_gmean(a, b);<br /> }</p><p> return std::sqrt(a * b);<br />}</p><p>double means(double a, double b) throw(bad_hmean, bad_gmean)<br />{<br /> double am, hm, gm;<br /> demo d2("found in means()");<br /> am = (a + b) / 2.0; // arithmetic mean<br /> try<br /> {<br /> hm = hmean(a, b);<br /> gm = gmean(a, b);<br /> }<br /> catch (bad_hmean & bg) // start of catch block<br /> {<br /> bg.mesg();<br /> std::cout << "Caught in means()/n";<br /> throw; // rethrows the exception<br /> }<br /> d2.show();</p><p> return (am + hm + gm) / 3.0;<br />}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.