在程式的一般設計中,怎麼判定一個方法適合按你預想的那樣執行了,在C語言中,返回一個整數是常用的方法,比如一個-1,比如linux開啟一個檔案open,失敗返回-1,大家如果都遵守還好,可是還是會出現返回0是失敗的。Java中對於異常錯誤處理使用異常,異常是強制使用的,在C++中不是,你可以完全不使用,說實話我很好使用,有時基本都忘了,使用的最多的還是C的風格,這兩個對於異常處理的風格沒有孰優孰劣。C的風格簡單,明了。C++的異常,可以包含更多的資訊,方便日誌,調試。
標準庫中定義了異常類,可是那隻架構層次的,在實際使用中,如果確定使用異常處理來進行異常錯誤處理,那麼還需要在標準庫之上拓展,或者自己再造輪子。
今天我不會講在C++中使用異常的文法,只是講一些注意點。
1.在建構函式中拋出異常
在建構函式中拋出異常,那說明什麼,物件建構沒成功,那麼你精心設計的解構函式就可能沒法調用,在建構函式中如果在拋出之前你什麼的佔用了一些資源,那必須你自己手動的釋放。
比如這樣:
A::A(){ p = new int[10]; //上面的記憶體配置完成,然後你拋出一個異常}A::~A(){ delete[] p;}
2.不能讓解構函式拋出異常,有問題內部解決
解構函式是資源管理的不可多得的還途徑,不管什麼情況,請保證它執行完。
在基層體系中,你可能回擔心在子類的解構函式中拋出異常,那父類的解構函式還會調用嗎?我們先來看看類構造的順序,我們只談構造時產生的,static關鍵字就不談了。
下面程式碼範例:
#ifndef SUPER_HPP#define SUPER_HPP#include <iostream>/** * @brief The Super class 超類 父類 */class Super{public: Super() {std::cout << "Super\n";} virtual ~Super() {std::cout << "Super 析構\n";}};#endif // SUPER_HPP#ifndef SUB_HPP#define SUB_HPP#include "super.hpp"class A{public: A() {std::cout << "A\n";} virtual ~A(){std::cout << "A 析構\n";}};/** * @brief The Sub class 子類 */class Sub : public Super{public: Sub():Super() {std::cout << "Sub\n";} virtual ~Sub(){throw 1;std::cout << "Sub 析構\n";}protected:private: A a;};#endif // SUB_HPP
#include "sub.hpp"int main(){ Sub *s = new Sub(); try { delete s; }catch(int i) { std::cout << i << std::endl; }}
如結果所示,父類先構造,然後是資料成員然後調用建構函式。C++會保證完全構造的對象是調用它的解構函式,所以前面的在有階層的類中的建構函式中拋出異常也是如此。不過拋出異常的解構函式不會調用完成,如少輸出一句話,如果後續還有資源釋放操作,那就會造成泄漏。