c++ primer plus 第15章友,異常和其他 15.3.11 有關異常的注意事項
15.3.11 有關異常的注意事項
文章目錄
- c++ primer plus 第15章友,異常和其他 15.3.11 有關異常的注意事項
- 15.3.11 有關異常的注意事項
15.3.11 有關異常的注意事項
從前面關于如何使用異常的討論可知,應在設計程序時就加入異常處理功能,而不是以后再添加。這樣做有些缺點。例如,使用異常會增加程序代碼,降低程序的運行速度。異常規范不適用于模板,因為模板函數引發的異常可能隨特定的具體化而異。異常和動態內存分配并非總能協同工作。下面進一步討論動態內存分配和異常。首先,請看下面的函數:
void testl(int n)
{
string mesg("I'm trapped in an endless loop");i
if (oh_no)throw exception();...
return;
}
string 類采用動態內存分配。通常,當函數結束時,將為mesg 調用string 的析構函數。雖然 throw語句過早地終止了函數,但它仍然使得析構函數被調用,這要歸功于棧解退。因此在這里,內存被正確地管理。
接下來看下面這個函數:
void test2(int n)
{
double*ar = new double[n];...
if (oh_no)
throw exception);
...
delete [] ar;
return;
}
這里有個問題。解退棧時,將刪除棧中的變量ar。但函數過早的終止意味著函數末尾的 delete[]語句被忽略。指針消失了,但它指向的內存塊未被釋放,并且不可訪問。總之,這些內存被泄漏了。這種泄漏是可以避免的。例如,可以在引發異常的函數中捕獲該異常,在catch塊中包含一些清理代碼,然后重新引發異常:
void test3(int n)
{
double*ar=new double[n];
try{
if(oh_no)
throw exception()
}
catch(exception & ex)
{delete [] arr;throw;
}
... delete []arr;
return ;
}
然而,這將增加疏忽和產生其他錯誤的機會。另一種解決方法是使用第16章將討論的智能指針模板
總之,雖然異常處理對于某些項目極為重要,但它也會增加編程的工作量、增大程序、降低程序的速度。另一方面,不進行錯誤檢查的代價可能非常高。
異常處理
在現代庫中,異常處理的復雜程度可能再創新高--主要原因在于文檔沒有對異常處理例程進行解釋或解釋得很整腳。任何熟練使用現代操作系統的人都遇到過未處理的異常導致的錯誤和問題。這些錯誤背后的程序員通常面臨一場艱難的戰役,需要不斷了解庫的復雜性:什么異常將被引發,它們發生的原因和時間,如何處理它們,等等。 程序員新手很快將發現,理解庫中異常處理像學習語言本身一樣困難,現代庫中包含的例程和模式可能像 C++語法細節一樣陌生而困難。要開發出優秀的軟件,必須花時間了解庫和類中的復雜內容,就像必須花時間學習 C++本身一樣。通過庫文檔和源代碼了解到的異常和錯誤處理細節將使程序員和他的軟件受益。