亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C++的錯誤和異常處理分析

2019-11-17 05:28:11
字體:
來源:轉載
供稿:網友
何時使用異常?

  一個簡單的回答是:“當異常的語義和性能要求都恰當的時候?!?br />
  一個經常被提到的方法是這樣問自己:“這是一個例外(或者意外的)情形嗎?”這個方法貌似挺吸引人,但是通常只會導致錯誤答案。對一個人來說是“異常”的情形對另一個人卻“正?!保寒斈阏嬲屑毧紤]這句話時,就發現無法作出區分,這句話根本幫不了你。究竟,假如你檢查了某個錯誤條件,就意味著你認為它會發生,否則你的檢查不過是垃圾代碼。

  一個更合適的問法是:“這里需要棧展開嗎?”由于異常處理實際上幾乎都意味著比正常流程代碼要慢,還應該問自己:“這里負擔得起棧展開的代價嗎?”比如,正在做的一個要花很長時間的計算,并且周期性地檢測用戶是否按下了取消鍵。拋出異常可以優雅地取消操作。另一方面,在這個計算的內部循環中拋出并捕捉處理異??赡芫筒磺‘?,這么做可能導致嚴重的性能下降。前述內容包含這樣一個原則:對于時間要害的代碼,拋出異常才是一種“異?!钡淖龇?,而不是常規.

  如何設計異常類?

  1. 從std::exception派生異常類。除了一些非常罕見的情況,例如負擔不了需函數的開銷。把std::exception作為異?;愂呛侠淼?,當它被廣泛使用后,將答應程序員捕捉任何異常而不必使用catch(...).更多關于catch(...)的內容,請看后文。

  2. 使用虛擬繼續。這個深刻的洞察力來自Andrew Koenig. 當拋出的一個異常是從多個基類派生,并且這些基類有共同的部分,catch點就會碰到歧義問題,從異?;愄摂M繼續可以防止這種歧義問題:

#include <iostream>
strUCt my_exc1 : std::exception { char const* what() const throw(); };
struct my_exc2 : std::exception { char const* what() const throw(); };
struct your_exc3 : my_exc1, my_exc2 {};

int main()
{
try { throw your_exc3(); }
catch(std::exception const& e) {}
catch(...) { std::cout << "whoops!" << std::endl; }
}
  上面的程序將打印出“whoops” ,因為C++運行時刻無法決定用那個exception實例去匹配第一個catch.(禿子:我的建議是這里最好別使用多重繼續)

  3. 不要內嵌std::string對象或者其他拷貝構造可能拋出異常的數據成員、基類。在上述點拋出異常將導致直接調用std::terminate().讓基類或數據成員的默認構造函數可能拋出異常也是同樣糟糕的主意,你本來是打算通過一個包含對象構造的throw表達式報告異常, 程序卻無謂地中止了:

throw some_exception();

  當發生異常拷貝時,有幾種方法避免復制字符串對象,例如在異常對象中嵌入一個定長存儲區,或者通過引用計數來治理字符串。不過,在采用這些方法前,先考慮考慮下一條。

  4. 只在確實需要的時候才格式化what()返回的信息。格式化是一個典型的內存相關的操作,有可能拋出異常。最好把格式化推遲到棧展開之后,因為棧展開可能釋放某些資源。對what()函數用catch(...)塊加以保護是一個好主意,這樣你就可以在格式化拋出異常時有了一個退路。

  5. 不要太在意what()的信息。在異常拋出點,對程序員來說,這是給出錯誤信息的好機會,但是你未必能夠把相關信息組合成用戶可以理解的形式。國際化就一個典型的情況。Peter Dimov給出了良好建議:建一個錯誤信息格式化的表格,把what()的字符串作為這個表的鍵。當標準庫拋出異常時,假如我們只能獲得其標準的what()字符串……

  6. 在異常類的public接口中暴露導致錯誤的有關信息。返回固定信息的what()意味著你忽視了暴露信息,而用戶可能需要提供相關信息。例如,你的異常想報告數字范圍錯,報錯的代碼應該能夠透過異常的公共接口讓異常包含導致問題的那個變量值。假如你只是在what()中以文本方式表現這些數字,那些需要根據信息做更多(或更少)處理的程序員日子將很難過。

  7. 假如可能,讓你的異常類對兩次析構免疫。幾款流行的編譯器偶然會使異常對象被銷毀兩次。假如你能采取措施防御危害(比如,把釋放的指針置零)就可以使代碼更健壯。

  如何處理程序員犯錯?

  作為開發者,假如我違反了所使用庫的某個前條件,我不希望棧展開。我希望的是core dump或者等價物—一個能精確地在問題發生點檢查程序狀態的方法。這通常意味著assert()或者其他類似的東西。

  有時候為用戶提供可以應付任意誤用的強健的API是有必要的,但這樣通常要付出不菲的代價。比如,一個常見需求是跟蹤客戶使用的每一個對象,從而可以驗證合法性。假如你需要這種保護,通常是在一個簡單API上再封裝一層來實現。盡管你做得小心翼翼,有強健承諾的API也只能防御某些而不是所有會導致災難的誤用??蛻粢查_始依靠那些保護并且所依靠的保護也將增長到接口保護不到的部分。

  windows開發者請注重:當你使用assert()時,大部分Windows編譯器實際上都是拋出異常,并且被本地截獲,這很不幸。事實上,截獲的錯誤經常是段訪問失敗或者除零錯。當你使用JIT(Just In Time)調試時這是個問題,這意味著在在喚醒調試器之前已經異常棧展開了,因為catch(…)將捕捉這個異常,其實這個并非C++異常。幸運的是,有一個鮮為人知的簡單辦法可以處理:

extern "C" void straight_to_debugger(unsigned int, EXCEPTION_POINTERS*)
{
throw;
}
extern "C" void (*old_translator)(unsigned, EXCEPTION_POINTERS*)= _set_se_translator(straight_to_debugger);
  這個方法無法應付在catch塊中(或者catch塊調用的函數中)拋出結構化異常的情況,但它確實可以解決絕大多數JIT導致的問題。

  該如何處理異常?

  壓根就不處理異常一般是處理異常的最好辦法。假如你讓異常穿越你的代碼,并且在析構函數中做清理工作,代碼會更干凈。

  盡可能避免catch(…)

  很不幸,其他非Windows操作系統一樣會把非C++異常(例如線程中止)卷入到C++異常機制中去,而且,有時候也沒有類似上面提到的_set_se_translator這樣的hack手法加以解決。我們通常在析構函數或者catch塊中做合理操作來維持系統的不變式,這通常是安全的。然而catch(...)也會捕捉非預期的系統通知,這時是不可能像對待普通C++異常一樣來處理的,慣用的手法不再安全了。

  經過新聞組上長期的辯論之后,盡管不情愿,我還是得承認Hillel Y. Sims觀點:除非所有操作系統修正前面的問題,否則,所有異常應該繼續自std::exception,當所有人適應catch(std::exception&)而不是catch(...)時,世界將會更加美好。

  即使不考慮和操作系統間糟糕的交互情況,有時候,catch(...)仍然是最合適的選擇。假如你根本不知道會有什么異常拋出,并且必須停止棧展開,這可能是你唯一出路。一個典型的情況就是跨語言的時候。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美黄色小视频| 一本大道亚洲视频| 国产一区二区精品丝袜| 91免费电影网站| 国产亚洲精品日韩| 亚洲精品久久久一区二区三区| 亚洲一区二区久久久| 欧美极品欧美精品欧美视频| 欧美精品久久久久久久免费观看| 国产情人节一区| 日韩精品一区二区视频| 91在线视频精品| 这里只有视频精品| 91a在线视频| 2021久久精品国产99国产精品| 国产亚洲精品综合一区91| 国产欧美日韩专区发布| 中文在线资源观看视频网站免费不卡| 91av在线播放视频| 欧美性xxxxx极品| 欧美性受xxx| 日韩av影视在线| 色yeye香蕉凹凸一区二区av| 日韩精品免费在线观看| 少妇激情综合网| 精品无人区太爽高潮在线播放| 琪琪亚洲精品午夜在线| 欧美性xxxx极品高清hd直播| 久久成人精品一区二区三区| 51ⅴ精品国产91久久久久久| 日韩欧美亚洲一二三区| 日本免费久久高清视频| 国产啪精品视频| 在线播放日韩精品| 欧美激情国产日韩精品一区18| 日韩精品中文字幕有码专区| 久久久久国产精品www| 大胆人体色综合| 日韩视频中文字幕| 久久精品国产亚洲一区二区| 精品久久久久人成| 国产精品一区二区女厕厕| 中文字幕久久久| 亚洲自拍偷拍在线| 欧美日韩午夜剧场| 亚洲人成电影在线观看天堂色| 国产精品久久久久999| 欧美性猛交xxxx富婆弯腰| 91香蕉嫩草影院入口| 91中文字幕在线| 国内偷自视频区视频综合| 久久好看免费视频| 国产精品第七影院| 欧美激情国内偷拍| 精品国产拍在线观看| 欧美日韩美女视频| 精品露脸国产偷人在视频| 亚洲精品久久久久久久久久久久久| 久久69精品久久久久久久电影好| 国产一区二区在线播放| 午夜精品一区二区三区视频免费看| 亚洲久久久久久久久久久| 亚洲精品电影网在线观看| 久久av中文字幕| 91国内揄拍国内精品对白| 欧美成人国产va精品日本一级| 欧美日韩在线观看视频| 日韩电影在线观看中文字幕| 欧美性极品xxxx娇小| 国产欧美一区二区三区在线| 欧美性xxxxx极品娇小| 91在线精品播放| 国产婷婷色综合av蜜臀av| 日韩免费av一区二区| 欧美在线激情网| 日韩视频在线免费观看| 97视频免费观看| 日韩av在线免播放器| 国产精品高清在线| 色播久久人人爽人人爽人人片视av| 亚洲第一级黄色片| 日韩中文字幕视频在线| 国产精品九九久久久久久久| 久久久精品国产一区二区| 91精品国产电影| 久久午夜a级毛片| 久久国产精品久久久| 美女av一区二区| 亚洲一级片在线看| 亚洲欧美日韩国产精品| 91中文字幕在线| 国产盗摄xxxx视频xxx69| 欧美日韩一区二区免费在线观看| 成人性生交大片免费观看嘿嘿视频| 国产精品欧美在线| 成人高清视频观看www| 欧美美女操人视频| 精品香蕉在线观看视频一| 欧美激情乱人伦| 亚洲精品国产精品国自产观看浪潮| 亚洲自拍偷拍色片视频| 日本人成精品视频在线| 久久深夜福利免费观看| 欧美大学生性色视频| 亚洲第一偷拍网| 亚洲精美色品网站| 亚洲一区二区久久久| 57pao成人国产永久免费| 红桃视频成人在线观看| 久久久免费av| 欧美性猛交xxxx黑人| 亚洲一级片在线看| 久久精品中文字幕电影| 北条麻妃久久精品| 精品国产老师黑色丝袜高跟鞋| 欧美精品一区二区免费| 久久国产天堂福利天堂| 色妞色视频一区二区三区四区| 日本道色综合久久影院| 亚洲va欧美va国产综合久久| 国产婷婷色综合av蜜臀av| 日韩精品在线电影| 亚洲高清av在线| 亚洲色图13p| 国产一区二区三区在线免费观看| 91精品一区二区| 91精品久久久久久久久久另类| 久久免费高清视频| 亚洲精品白浆高清久久久久久| 国产精品久久久久久av下载红粉| 亚洲专区国产精品| 色偷偷综合社区| 亚洲欧美日韩精品久久亚洲区| 庆余年2免费日韩剧观看大牛| 在线电影欧美日韩一区二区私密| 久久久久久这里只有精品| 九九热这里只有精品免费看| 亚洲最大在线视频| zzjj国产精品一区二区| 欧美性生交大片免网| 在线播放亚洲激情| 最新中文字幕亚洲| 国产欧美日韩中文字幕| 久久这里只有精品视频首页| 在线观看欧美日韩国产| 国产精品男人爽免费视频1| 欧美大肥婆大肥bbbbb| 欧美激情区在线播放| 97在线免费观看| 日本不卡视频在线播放| 日韩久久午夜影院| 国产日韩欧美自拍| 精品视频久久久久久久| 91在线无精精品一区二区| 色爱av美腿丝袜综合粉嫩av| 色无极影院亚洲| 亚洲成人精品久久久| 久久乐国产精品| 综合激情国产一区| 亚洲精品一区二三区不卡| 亚洲久久久久久久久久| 久久精品国产欧美激情| 久久亚洲精品一区二区| 久久久成人av|