用C++ 而不是 用c (4)使用異常和傳回值

來源:互聯網
上載者:User

使用異常和傳回值
1.使用傳回值處理錯誤需要程式員嚴格的編程作風,程式員不論是否有這種習慣,這都是非常不希望的。
2.正確的異常處理是C++中的一個常識。異常通過發出錯誤訊號,可以讓程式碼和錯誤處理代碼分開,而且不會讓程式忽略錯誤。
3.必須瞭解使用了哪種錯誤處理方法,傳回值還是拋出異常。如果不知道,那麼你的程式肯定有問題。
4.異常是基於每個線程而提出並處理的;異常不能被線程忽略,必須被處理;未處理的異常會使進程結束,而不僅僅是線程結束;異常處理在釋放棧時會釋放所有的棧對象,因此避免了資源的漏洞;異常處理需要大量的額外操作,使得它並不適於經常啟動並執行代碼。詳細的說,catch塊有一些開銷(overhead),但是try塊有很少的開銷;因此只有在拋出異常的時候才會有很多的異常操作開銷;你可以拋出任何類型的異常對象,但不包括整數。
5.傳回值可以指示正常和不正常的函數運行,但不能阻止線程的繼續運行;傳回值很容易被忽略;傳回值在典型的情況下是一個整數,通常映射符合於一個預定義的值;傳回值能高效的傳遞和接收;
6.所有的非錯誤的狀態資訊都應該使用傳回值
7.傳回值用於大多數情況下可以隨意忽略而不會出現問題的錯誤
8.在迴圈中的錯誤處理必須快速,因為異常的額外開銷,所以為了得到更好的效能,使用傳回值是一個更好的選擇。在這種情況下,如果你真要使用異常,可以建立一個函數來將傳回值轉化未異常。
9.使用於中繼語言模組中的錯誤。
10.使用Windows API的錯誤處理機制。用SetLastError設定錯誤碼,通過GetLastError檢測這個錯誤碼。
11.從C++異常處理的觀點看,故障應該被認為是錯誤。
12.你必須使用/Eha調試器選項來撲獲使用C++異常操作機制的作業系統異常。
14.Windows結構異常處理:使用_try,_except,_finally,_leave關鍵字和RaiseException API函數;由Windows支援,不適於其他動作系統;不處理C++對象的解析;作為硬體異常或作業系統異常的結果拋出,也可作為RaiseException函數結果被拋出。
15.C++異常處理:使用try,throw和catch等關鍵字;僅被C++語言支援;處理C++對象的解析;可以拋出任何類型的C++對象。異常對象可以從標準的異常基本類派生,也可以從任何類派生,或者它們也可以是內建的類型;作為throw語句的結果被拋出。
16.Visual C++ 使用結構異常處理機制實現C++異常。
17.結構異常處理不能處理對象的解析,因此你應該在C++程式中一直使用C++異常。然而,因為C++異常不能處理硬體和作業系統異常,你的程式需要將結構異常轉化為C++異常。
18.為了正確處理硬體和作業系統異常,你可以建立自己的異常類並使用_set_se_translator函數安裝一個結構異常向C++異常的轉化器。
19.不要撲獲那些不能恢複所產生問題的轉化後的結構異常。
20.在很少拋出異常的情況下使用異常的代價並不是很大,而且這樣做確實可以提高效能。
21.異常策略中最重要的一部分實際上就是有一個策略。不要在事後彌補。
22.異常撲獲規則:撲獲處理器按順序提供;如果撲獲處理器撲獲了同一類型或指向同一類型拋出對象的指標,則應撲獲異常。如果撲獲處理器撲獲了一個公用基類或者指向一個公用基類拋出對象的指標,則應撲獲異常;一個省略撲獲處理器撲獲任何類型的異常,因此它總是放在最後。
23.定義一個異常基類來處理常式代碼拋出的異常。
 class CProgramException : public exception {
 public:
 CProgramException (const _exString &_what_arg) :
  exception(_what_arg) {}
};
使用CProgramException類使得異常處理更加簡單,因為可以通過處理這種基類撲獲所有的程式中的異常。如果需要的話,也可以使用額外的成員資料全面描述特定的問題。
24.使用auto_ptr或者一個類似的指標類通過限制局部變數的動態分配來自動釋放資源:
void LeakFreeFunction (int arg) {
 auto_ptr<CMyObject> pObject(new CMyObject(arg));
 ... // do something that throws an exception
 // can still call member functions as normal
 pObject->MemberFunction();
 // no need to delete pObject
}
注意:auto_ptr僅在使用delete釋放資源時使用。
25.使用異常處理更簡單,更可靠,更有效,可以建立更健壯的代碼。然而,你應該只在意外的情況下使用異常處理。如果你認為一個指標應該時空值,這種條件下就直接在代碼中檢查這個值,而不要使用異常。
26.非MFC的C++異常應該通過引用來撲獲。使用引用撲獲異常不需要刪除異常對象(因為使用引用撲獲的異常會在棧中傳送),而且它保留了多態性(因此你撲獲的異常對象正是你拋出的異常對象)。使用指標撲獲異常需要你刪除對象,而使用值撲獲對象會導致對象的“分區”(slicing),也就是說,將派生的異常對象轉化為撲獲的資料類型。
27.MFC異常應該通過指標來撲獲。因為它們通常從堆中分配,當你處理完異常之後,你需要調用Delete成員函數:
...
catch (CFileException *e) {
 // handle file exception
 ...
 e->Delete(); // required to prevent a memory leak
}
因此,你不可以使用省略撲獲處理器撲獲MFC異常,因為者會導致一個記憶體流失。你必須使用Delete成員函數刪除MFC異常,而不要用delete操作符,因為一些MFC異常作為靜態對象建立。
28.一旦撲獲了異常,你可以通過執行下列典型動作的一些組合來處理它:
 (1) 什麼也不要做。
 (2) 修改這個問題並重試代碼。
 (3) 修改這個問題但不要重試代碼。
 (4) 如果使用者需要的話,向使用者顯示錯誤資訊。
 (5) 如果出現的問題不是程式錯誤的話,輸出一個診斷的跟蹤訊息。
 (6) 如果出現的問題是程式錯誤,輸出一個斷言。
 (7) 在記錄檔中記錄這個問題。
 (8) 如果異常是不可恢複的,停止進程的運行。
 (9) 整理已指派的資源。
 (10) 重新拋出這個異常,使得進階函數也能處理這個異常,特別是在當前函數不能完全解決的情況下。你可以重新拋出同一個異常對象,或拋出一個新的異常對象。
29.和/EHa相對的是同步異常(/EHs),而不是/GX。/GX實際上是/EHsc的簡化形式。/GX表示編譯器應該假設extern "C" 的函數不拋出C++異常,而/EHs則拋出。
30.為使用者和調用環境記錄異常。通常,異常物件類型用於向調用環境通知出現的問題,而問題的描述字串用於向使用者通知。
31.Visual C++的預設情況下,new和malloc對於錯誤不會拋出異常,但你可以通過使用_set_new_handler安裝一個處理器,讓new針對錯誤拋出異常。你也可以讓malloc通過調用_set_new_mode使用同一處理器。
#include <new.h>

class bad_alloc : public exception {
public:
 bad_alloc(const __exString& what_arg) : exception (what_arg) {}
};

int NewHandler (size_t size) {
 throw bad_alloc("Operator new couldn't allocate memory");
 return 0;
}

int APIENTRY WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,int nCmdShow) {
 _set_new_handler(NewHandler);
 _set_new_mode(1);   // use NewHandler for malloc as well
 ...
}

32.如果已存在的代碼中沒有設定new返回空值,那麼你應該始終讓new出錯時拋出一個異常。
33.浮點數和整數不一樣,在預設情況下它被零除不會出現異常,但是會出現一個非常奇怪的值"1.#INFO" (它表示這個值並不是一個數字)。要讓檢測浮點數問題更簡單一些,你應該用如下的代碼讓浮點數錯誤拋出異常。
#include <float.h>
int cw=controlfp(0,0);
cw &= ~(EM_OVERFLOW | EM_UNDERFLOW | EM_INEXACT | EM_ZERODIVIDE | EM_DENORMAL | EM_INVALID);
_controlfp(cw, MCW_EM);
浮點數異常處理器必須調用_clearfp作為它的第一條指令來清空浮點數異常。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.