為“異常”努力是值得的

異常是OO語言處理錯誤的方式,在C++中,鼓勵使用異常。侯捷再書中談起異常,“十年前撰寫“未將異常考慮在內的”函數是為一種美好實踐,而今我們致力于寫出“異常安全碼”。”可見異常安全的重要。

說起異常安全,首先就要是異常的出現是為彌補C語言缺陷。再者,將介紹異常的概念,異常安全的條件。

C語言處理錯誤的缺陷

  • 程序意外終止

? ? ? ????????? 比如:內存申請錯誤,越界,除0錯誤,會直接終止程序

  • 錯誤碼難以解讀

? ? ????????? ? 在出錯后會返回一個數字(錯誤碼)。此時會包含倆層含義:是錯誤信息?是結果?

? ? ? ? ????????錯誤碼需要程序員查找相關庫信息

? ? ?出現錯誤直接終止程序是非常不允許的情況。

C++異常的引入

異常:當一個函數出現自己無法解決的錯誤時,可以拋出異常,讓函數的直接或間接調用者處理這個問題。

處理異常的三個關鍵字:

throw:當問題出現時,要拋出異常,通過throw拋出

catch:用于捕獲異常。可以有多個catch

try:try中的代碼將被激活特定的異常,try后跟著一個或多個catch塊。

try要和catch匹配使用。

catch塊中的內容不一定會被執行,只有當異常拋出且被捕獲時才會執行,否則不執行。

	try {//保護塊}catch (ExceptionName e1){//}catch (ExceptionName e2){//}

異常的拋出與匹配規則

  • 異常是有拋出對象引發的,該對象類型決定調用哪個塊的。比如:拋出int類型的異常,catch參數為int的來接收。實際上:拋出和捕獲類型不一定要相同,這里可以拋出派生對象。


  • 選中的處理代碼是調用鏈中與該對象類型匹配且離拋出異常位置最近的那一個。


  • 異常拋出的對象后,會生成一個臨時拷貝,傳給catch

在實際運用中,拋異常拋出通常對象是一個類,包含錯誤信息和錯誤碼。

由于私有成員在內外拿不到,故通過函數調用返回錯誤信息和錯誤碼。

對于臨時拷貝的類型是const 故函數要添加const,才可調用。


  • catch(...)可以捕獲任意類型的對象。

拋出的異常在沒有繼承情況下,要匹配相應的類型才能被捕獲,會在catch中一直匹配,直到catch(...)處理任意類型。但是無法得到拋出的異常對象。

異常的重新拋出

對于內存資源申請,拋異常要極為謹慎。
在上述的例子中,雖然有對內存資源釋放,但是拋異常后捕捉異常跨越棧幀,導致內存沒有被釋放。內存的申請沒有釋放是一件很嚴重的事情。
在這里,希望能在main函數中,將內存釋放。
我們必須將異常重新拋出,在Func函數中,捕獲異常,再將異常重新拋出。

異常安全


具有異常安全的函數會

  • 不泄露任何資源。例如上述代碼在拋出異常后,后續的delete不會被調用。
  • 不允許數據敗壞。異常拋出后,異常被捕獲,導致棧幀的跳躍,關鍵信息沒有被執行。

解決資源泄露是比較輕松的

確保析構,智能指針。

這里我們專注解決數據敗壞的問題。

在構造函數中,最好不要拋異常,可能會導致沒有完全構造

析構過程最好不好拋異常

在lock和unlock拋異常會導致死鎖

異常安全函數有以下三個保證

  • 基本承諾

????????如果異常被拋出,程序內任何事物都保持在有效狀態,沒有任何對象和數據結構被破壞,所有對象處于一種內部前后一致的狀態。

  • 強烈保證

? ? ? ? 如果函數調用成功,就完全成功。如果函數失敗,程序就恢復到調用之前狀態。

  • 不拋擲保證

? ? ? ? 承諾異常絕不拋出,因為它們總能夠完成它們原先承諾的功能。

在C++11中,如果一個函數明確的不拋異常的話,就用noexcept

thread() noexcept;
thread (thread&& x) noexcept;

異常優點

  • 可以清晰展示錯誤信息
  • 拋異常可以直接拿到錯誤信息,不需要重重返回。
  • 第三方庫的異常安全很規范
  • 部分函數更好檢查。如構造函數沒有返回值。

缺點

執行的跳躍,亂流。追蹤程序困難。

C++沒有垃圾回收機制,異常任意導致內存泄漏

標準庫的異常不完善。

異常是被鼓勵使用。時間不斷前進,我們與時俱進!

參考:
<<Effective c++>>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/207040.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/207040.shtml
英文地址,請注明出處:http://en.pswp.cn/news/207040.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Leetcode—213.打家劫舍II【中等】

2023每日刷題&#xff08;五十二&#xff09; Leetcode—213.打家劫舍II 算法思路 實現代碼 class Solution { public:// 左閉右開int rob1(vector<int>& nums, int start, int end) {int n nums.size();int f0 0, f1 0, new_f 0;for(int i start; i < end…

pytorch學習入門之 Variable(變量)

Variable(變量) autograd.Variable 是包的核心類. 它包裝了張量, 并且支持幾乎所有的操作. 一旦你完成了你的計算, 你就可以調用 .backward() 方法, 然后所有的梯度計算會自動進行. 你還可以通過 .data 屬性來訪問原始的張量, 而關于該 variable(變量)的梯度會被累計到 .…

初識 OpenCV

初識 OpenCV 簡介 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一個涵蓋了數百種計算機視覺算法的開源算法庫。 OpenCV 具有模塊化結構&#xff0c;這意味著該軟件包包含多個共享或靜態庫。其中包含以下模塊&#xff1a; Core functionality (core…

機器學習硬件十年:性能變遷與趨勢

本文分析了機器學習硬件性能的最新趨勢&#xff0c;重點關注不同GPU和加速器的計算性能、內存、互連帶寬、性價比和能效等指標。這篇分析旨在提供關于ML硬件能力及其瓶頸的全面視圖。本文作者來自調研機構Epoch&#xff0c;致力于研究AI發展軌跡與治理的關鍵問題和趨勢。 &…

【送書活動四期】被GitHub 要求強制開啟 2FA 雙重身份驗證,我該怎么辦?

記得是因為fork了OpenZeppelin/openzeppelin-contracts的項目&#xff0c;之后就被GitHub 要求強制開啟 2FA 雙重身份驗證了&#xff0c;一拖再拖&#xff0c;再過幾天帳戶操作將受到限制了&#xff0c;只能去搞一下了 目錄 2FA是什么為什么要開啟 2FA 驗證GitHub 欲在整個平臺…

消息隊列 - RabbitMQ

消息隊列 - RabbitMQ 1. 初識 MQ1.1 同步調用1.2 異步調用1.3.技術選型 2. RabbitMQ2.1 安裝2.2 收發信息2.2.1 交換機(Exchange)2.2.2 隊列2.2.3 綁定關系2.2.4 發送消息 2.3 數據隔離 1. 初識 MQ 微服務一旦拆分&#xff0c;必然涉及到服務之間的相互調用&#xff0c;之前講…

MySQL六 | 存儲引擎

目錄 存儲引擎 存儲引擎特點 存儲引擎選擇 Innodb與MyISAM區別 存儲引擎 默認存儲引擎:InnoDB show engines;#展示當前數據庫支持的存儲引擎 存儲引擎特點 特點InnoDBMyISAMMemory存儲限制64TB有有事務安全支持--鎖機制行鎖表鎖表鎖Btree鎖支持支持 支持 Hash索引--支…

編譯 Android gradle-4.6-all.zip 報錯問題記錄

編譯 Android gradle-4.6-all.zip 報錯問題記錄 方法一&#xff1a;替換資源&#xff1a;方法二&#xff1a;修改源方法三&#xff1a;修改版本 編譯時候無法下載 gradle-4.6-all Downloading https://services.gradle.org/distributions/gradle-4.6-all.zip 方法一&#xf…

《一念關山》熱度破萬,愛奇藝古裝賽道出盡風頭

?劉詩詩重回古裝劇、新式武俠公路片、質感細膩的鏡頭美學......看點滿滿的《一念關山》頻頻登上熱搜&#xff0c;俘獲了大批觀眾的心。 開播首日熱度就刷新了愛奇藝2023年站內紀錄&#xff0c;《一念關山》作為2023年愛奇藝在古裝賽道的收官之作&#xff0c;口碑和熱度兼收。…

Linux內核-標準IO和系統IO的區別

概念 標準IO&#xff1a;指的是C語言實現的文件操作的函數 系統IO&#xff08;文件IO&#xff09;&#xff1a;指的是linux或windows或unix&#xff0c;實現文件操作的函數。 為什么要有兩種IO C語言要實現跨平臺&#xff0c;所以C語言在不同操作系統中實現文件操作方式是不一…

一文詳解Java反射

文章目錄 反射是什么&#xff1f;反射的作用所有方法匯總一、加載Class對象二、加載類的構造器對象三、加載類的成員變量四、加載類的成員方法 反射是什么&#xff1f; 反射就是&#xff1a;加載類&#xff0c;并允許以編程的方式解剖類中的某個成分&#xff08;成員變量&#…

實戰:Docker Compose 下 Nginx、Java、Mysql 和 Redis 服務協同部署(包含解決瀏覽器訪問Linux部署服務器本地資源問題)

1. 背景 在該實戰中&#xff0c;我們將探討如何使用Docker Compose協同部署Nginx、Java、Mysql和Redis服務&#xff0c;實現一個視頻上傳與展示的應用。具體需求如下&#xff1a; Java應用負責上傳視頻和圖片資源到Nginx目錄下&#xff0c;作為資源服務器。Nginx服務作為靜態…

Numpy數組常用屬性匯總(第5講)

Numpy數組常用屬性匯總 (第5講) ??????? ??博主 侯小啾 感謝您的支持與信賴。?? ????????????????????????????????????????????????????????????????????????????????????…

【JavaEE進階】 Spring使用注解存儲對象

文章目錄 &#x1f334;序言&#x1f340;前置?作&#xff1a;配置掃描路徑&#x1f384;添加注解存儲 Bean 對象&#x1f333;類注解&#x1f6a9;為什么要這么多類注解&#x1f6a9;注解之間的聯系 &#x1f38b;?法注解 Bean&#x1f6a9;?法注解需要配合類注解使? ?總…

探索AIGC未來:CPU源碼優化、多GPU編程與中國算力瓶頸與發展

★人工智能&#xff1b;大數據技術;AIGC;Turbo;DALLE 3;多模態大模型&#xff1b;MLLM&#xff1b;LLM&#xff1b;Agent&#xff1b;Llama2&#xff1b;國產GPU芯片&#xff1b;GPU;CPU&#xff1b;高性能計算機&#xff1b;邊緣計算&#xff1b;大模型顯存占用&#xff1b;5G…

如何夸張孩子

你剛才很努力啊&#xff01;——表揚努力盡管艱難&#xff0c;但你一直沒有放棄——表揚耐心和堅持你做事情的態度非常不錯——表揚態度你在_____上進步了很多&#xff01;——表揚細節這個方法真有新意&#xff01;——表揚創意你和小伙伴合作得真棒&#xff01;——表揚合作精…

中國特供閹割版 RTX 4090 曝光,老黃這操作絕了

到了現在大伙兒應該發現&#xff1a;國內禁售 NVIDIA RTX 4090 顯卡這事兒基本實錘了。 實際上根據老美規定&#xff0c;從上個月 17 號開始&#xff0c;凡是公司主體在中國的顯卡品牌&#xff0c;就已經不能生產和銷售 RTX 4090。 以后廠商想要賣 4090 只能以整機形式出售&am…

藝術畫廊展廳網站制作的效果如何

藝術展廳往往有很多人前往&#xff0c;在主要城市有不少畫廊&#xff0c;對經營者來說&#xff0c;不同于銷售行業&#xff0c;其更多的是打造品牌吸引用戶前來或合作等形式&#xff0c;而由于行業特殊性&#xff0c;需要準屬性用戶才會前往。 因此在品牌打造及信息承載宣傳方…

防止企業敏感數據泄露

敏感數據泄露是指意外或故意泄露關鍵信息&#xff0c;例如個人身份信息&#xff08;PII&#xff09;、支付卡信息&#xff08;PCI&#xff09;、受保護的電子健康信息&#xff08;ePHI&#xff09;和知識產權&#xff08;IP&#xff09;&#xff0c;數據保護措施不足的組織會在…

10-Hadoop組件開發技術

單選題 題目1&#xff1a;下列選項描述錯誤的是&#xff1f; 選項: A Hadoop HA即集群中包含Secondary NameNode作為備份節點存在。 B ResourceManager負責的是整個Yarn集群資源的監控、分配和管理工作 C NodeManager負責定時的向ResourceManager匯報所在節點的資源使用情況…