异常的使用心得
工欲善其事,必先利其器.在做一個項目時必定要先做好調試除錯的準備在面向過程編程的時代都是以檢測
返回的錯誤代碼來判斷錯誤,可是這種方法的缺點是如果編寫某一操作的時候可能出現的錯誤代碼(比如說
硬件操作)太多,那么最終用戶將會陷入倒無窮無盡的檢測代碼中,可能會是這個樣子
UINT err=Functionxx(...);
if(err==xxx)
...
if(err==xxx)
...
...
...
省略100行
只有這樣程序才能在出現意外的時候有所相應和恢復,但是由于錯誤處理太龐大了最終用戶很可能這樣
if(Functionxx()!=SUCEEDED)
exit(0);
這樣某些可能可以恢復的操作也無法幸免了,(比如說網絡連接超時,終止運行太過分了吧,只要彈出個對話
框就行了)
在面向對象編程的時候,不可否認,很多人仍然還是這樣排錯的,其實各種面向對象的語言都提供了異常處
理的手段(比如說Object Pascal,C++,本文以C++為例)??
下面是我的關于異常的一些使用心得
對于各種用戶來說,并不是每一種錯誤都是他關心的,特別是小組開發的時候比如某一模塊是關于文件操作
的,那么編寫這個模塊的程序員只要注意關于文件操作失敗的異常就行了,而網絡模塊的程序員只要知道網
絡出錯的錯誤處理就行了,因此,我們可以定義一個這樣的類
class CBasicException
{
CBasicException(...);
char* GetDescription();
UINT GetErrorCode();
...
};
然后再從這個類繼承幾個子類
CFileException,CNetException...
然后和具體某一類錯誤相關的詳細的異常分別從上面的類里面繼承,比如文件打開失敗,空間不夠...等等
可以從CFileException繼承,而連接超時..等等可以從CNetException繼承,如此一來就將錯誤分類了整個
類層次是這樣的
CBasicException
/ /
CFileException CNetException
/ / / /??
COpenFailed ... CTimeOut ...
之后將各個錯誤碼和相應的異常對應起來,一些不太重要的信息可以封裝在一個異常里,比如文件打不開可
能是空間不夠或共享沖突...,都可以放在一起,如果以后要專門處理某一樣,比如空間不夠,再從相應的基
類繼承即可(COpenFialed)
然后你的函數應該這樣實現
CMyfunc()
{
...
throw Cxxx(...);
}
而在相應的調用部分則可以這樣寫
void Operation1()
{
try{
Myfunc()
}
catch(CFileException& e)//處理文件
{
printf("%s",e.GetDescription());
throw;//重新拋出,如果搞定就不用再拋出了
}
catch(CNetException& e)//網絡
{
...
throw;
}
}
這樣只要catch想要處理的異常就行了
但是你的主函數應該這樣寫
void main()
{
try{
Opertion1();
Operation2();
Operation.....
...
}
catch(Cxxx& e)//處理未捕獲的重要異常
{
...
}
catch(CBasicException& e)//對你所封裝的錯誤總的處理??
{
...
}
catch(...)//其他異常,未被封裝,比如除0
{
...
}
}
這樣處理就合理多了
而且如果在異常的描述里加上出錯地點就更好了,比如出錯函數名
不過千萬不要將異常基類的catch寫在子類的上面否則子類的catch可能永遠不會工作了??
比如:
try{
...
}
catch(CBasicException& e)
{
...
}
catch(CFileException(& e)
{
...
}
這樣后面的catch就再也不會被執行了
另外在類的構造函數和析構函數里不能返回值的,這時就只能用異常了 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
返回的錯誤代碼來判斷錯誤,可是這種方法的缺點是如果編寫某一操作的時候可能出現的錯誤代碼(比如說
硬件操作)太多,那么最終用戶將會陷入倒無窮無盡的檢測代碼中,可能會是這個樣子
UINT err=Functionxx(...);
if(err==xxx)
...
if(err==xxx)
...
...
...
省略100行
只有這樣程序才能在出現意外的時候有所相應和恢復,但是由于錯誤處理太龐大了最終用戶很可能這樣
if(Functionxx()!=SUCEEDED)
exit(0);
這樣某些可能可以恢復的操作也無法幸免了,(比如說網絡連接超時,終止運行太過分了吧,只要彈出個對話
框就行了)
在面向對象編程的時候,不可否認,很多人仍然還是這樣排錯的,其實各種面向對象的語言都提供了異常處
理的手段(比如說Object Pascal,C++,本文以C++為例)??
下面是我的關于異常的一些使用心得
對于各種用戶來說,并不是每一種錯誤都是他關心的,特別是小組開發的時候比如某一模塊是關于文件操作
的,那么編寫這個模塊的程序員只要注意關于文件操作失敗的異常就行了,而網絡模塊的程序員只要知道網
絡出錯的錯誤處理就行了,因此,我們可以定義一個這樣的類
class CBasicException
{
CBasicException(...);
char* GetDescription();
UINT GetErrorCode();
...
};
然后再從這個類繼承幾個子類
CFileException,CNetException...
然后和具體某一類錯誤相關的詳細的異常分別從上面的類里面繼承,比如文件打開失敗,空間不夠...等等
可以從CFileException繼承,而連接超時..等等可以從CNetException繼承,如此一來就將錯誤分類了整個
類層次是這樣的
CBasicException
/ /
CFileException CNetException
/ / / /??
COpenFailed ... CTimeOut ...
之后將各個錯誤碼和相應的異常對應起來,一些不太重要的信息可以封裝在一個異常里,比如文件打不開可
能是空間不夠或共享沖突...,都可以放在一起,如果以后要專門處理某一樣,比如空間不夠,再從相應的基
類繼承即可(COpenFialed)
然后你的函數應該這樣實現
CMyfunc()
{
...
throw Cxxx(...);
}
而在相應的調用部分則可以這樣寫
void Operation1()
{
try{
Myfunc()
}
catch(CFileException& e)//處理文件
{
printf("%s",e.GetDescription());
throw;//重新拋出,如果搞定就不用再拋出了
}
catch(CNetException& e)//網絡
{
...
throw;
}
}
這樣只要catch想要處理的異常就行了
但是你的主函數應該這樣寫
void main()
{
try{
Opertion1();
Operation2();
Operation.....
...
}
catch(Cxxx& e)//處理未捕獲的重要異常
{
...
}
catch(CBasicException& e)//對你所封裝的錯誤總的處理??
{
...
}
catch(...)//其他異常,未被封裝,比如除0
{
...
}
}
這樣處理就合理多了
而且如果在異常的描述里加上出錯地點就更好了,比如出錯函數名
不過千萬不要將異常基類的catch寫在子類的上面否則子類的catch可能永遠不會工作了??
比如:
try{
...
}
catch(CBasicException& e)
{
...
}
catch(CFileException(& e)
{
...
}
這樣后面的catch就再也不會被執行了
另外在類的構造函數和析構函數里不能返回值的,這時就只能用異常了 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
- 上一篇: Spatial Pyramid Pool
- 下一篇: 最大似然估计(MLE:样本观测总体参数)