欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++ 異常處理 catch(...)介紹

 更新時間:2013年09月16日 10:13:03   作者:  
catch(…)能夠捕獲多種數(shù)據(jù)類型的異常對象,所以它提供給程序員一種對異常 對象更好的控制手段,使開發(fā)的軟件系統(tǒng)有很好的可靠性

如果要想使一個catch block能抓獲多種數(shù)據(jù)類型的異常對象的話,怎么辦?C++標準中定義了一種特殊的catch用法,那就是” catch(…)”。
感性認識

1、catch(…)到底是一個什么樣的東東,先來個感性認識吧!
看例子先:

復(fù)制代碼 代碼如下:

 int main()
{
try
{
cout << "在 try block 中, 準備拋出一個異常." << endl;
//這里拋出一個異常(其中異常對象的數(shù)據(jù)類型是int,值為1)
throw 1;
}
//catch( int& value )
//注意這里catch語句
catch( …)
{
cout << "在 catch(…) block 中, 拋出的int類型的異常對象被處理" << endl;
}
}

2、哈哈!int類型的異常被catch(…)抓獲了,再來另一個例子:
復(fù)制代碼 代碼如下:

 int main()
{
try
{
cout << "在 try block 中, 準備拋出一個異常." << endl;
//這里拋出一個異常(其中異常對象的數(shù)據(jù)類型是double,值為0.5)
throw 0.5;
}
//catch( double& value )
//注意這里catch語句
catch( …)
{
cout << "在 catch(…) block 中, double類型的異常對象也被處理" << endl;
}
}

3、同樣,double類型的異常對象也被catch(…)塊抓獲了。是的,catch(..)能匹配成功所有的數(shù)據(jù)類型的異常對象,包括C++語言提 供所有的原生數(shù)據(jù)類型的異常對象,如int、double,還有char*、int*這樣的指針類型,另外還有數(shù)組類型的異常對象。同時也包括所有自定義 的抽象數(shù)據(jù)類型。例程如下:
復(fù)制代碼 代碼如下:

 int main()
{
try
{
cout << "在 try block 中, 準備拋出一個異常." << endl;
//這里拋出一個異常(其中異常對象的數(shù)據(jù)類型是char*)
char* p=0;
throw p;
}
//catch( char* value )
//注意這里catch語句
catch( …)
{
cout << "在 catch(…) block 中, char*類型的異常對象也被處理" << endl;
}
}
int main()
{
try
{
cout << "在 try block 中, 準備拋出一個異常." << endl;
//這里拋出一個異常(其中異常對象的數(shù)據(jù)類型是int[])
int a[4];
throw a;
}
//catch( int value[] )
//注意這里catch語句
catch( …)
{
cout << "在 catch(…) block 中, int[]類型的異常對象也被處理" << endl;
}
}

4、對于抽象數(shù)據(jù)類型的異常對象。catch(…)同樣有效,例程如下:
復(fù)制代碼 代碼如下:

 class MyException
{
public:
protected:
int code;
};
int main()
{
try
{
cout << "在 try block 中, 準備拋出一個異常." << endl;
//這里拋出一個異常(其中異常對象的數(shù)據(jù)類型是MyException)
throw MyException();
}
//catch(MyException& value )
//注意這里catch語句
catch( …)
{
cout << "在catch(…) block中, MyException類型的異常對象被處理" << endl;
}
}

對catch(…)有點迷糊?
1、究竟對catch(…)有什么迷糊呢?還是看例子先吧!
復(fù)制代碼 代碼如下:

void main()
{
int* p = 0;
try
{
// 注意:下面這條語句雖然不是throw語句,但它在執(zhí)行時會導(dǎo)致系統(tǒng)
// 出現(xiàn)一個存儲保護錯誤的異常(access violation exception)
*p = 13; // causes an access violation exception;
}
catch(...)
{
//catch(…)能抓獲住上面的access violation exception異常嗎?
cout << "在catch(…) block中" << endl;
}
}

請問上面的程序運行時會出現(xiàn)什么結(jié)果嗎?catch(…)能抓獲住系統(tǒng)中出現(xiàn)的access violation exception異常嗎?朋友們!和我們的主人公阿愚一樣,自己動手去測試一把!

結(jié)果又如何呢?實際上它有兩種不同的運行結(jié)果,在window2000系統(tǒng)下用VC來測試運行這個小程序時,發(fā)現(xiàn)程序能輸出"在catch(…) block中"的語句在屏幕上,也即catch(…) 能成功抓獲住系統(tǒng)中出現(xiàn)的access violation exception異常,很厲害吧!但如果這個同樣的程序在linux下用gcc編譯后運行時,程序?qū)霈F(xiàn)崩潰,并在屏幕上輸出”segment fault”的錯誤信息。

主人公阿愚有點急了,也開始有點迷糊了,為什么?為什么?為什么同樣一個程序在兩種不同的系統(tǒng)上有不同的表現(xiàn)呢?其原因就是:對于這種由于硬件或操作 系統(tǒng)出現(xiàn)的系統(tǒng)異常(例如說被零除、內(nèi)存存儲控制異常、頁錯誤等等)時,window2000系統(tǒng)有一個叫做結(jié)構(gòu)化異常處理(Structured Exception Handling,SEH)的機制,這個東東太厲害了,它能和VC中的C++異常處理模型很好的結(jié)合上(實際上VC實現(xiàn)的C++異常處理模型很大程度上建 立在SEH機制之上的,或者說它是SEH的擴展,后面文章中會詳細闡述并分析這個久富盛名的SEH,看看catch(…)是如何神奇接管住這種系統(tǒng)異常出 現(xiàn)后的程序控制流的,不過這都是后話)。而在linux系統(tǒng)下,系統(tǒng)異常是由信號處理編程方法來控制的(信號處理編程,signal processing progamming。在介紹unix和linux下如何編程的書籍中,都會有對信號處理編程詳細的介紹,當然執(zhí)著的主人公阿愚肯定對它也不會放過,會深 入到unix沿襲下來的信號處理編程內(nèi)部的實現(xiàn)機制,并嘗試完善改進它,使它也能夠較好地和C++異常處理模型結(jié)合上)。

那么C++標準中對于這種同一個程序有不同的運行結(jié)果有何解釋呢?這里需要注意的是,window2000系統(tǒng)下catch(…)能捕獲住系統(tǒng)異常, 這完全是它自己的擴展。在C++標準中并沒有要求到這一點,它只規(guī)定catch(…)必須能捕獲程序中所有通過throw語句拋出的異常。因此上面的這個 程序在linux系統(tǒng)下的運行結(jié)果也完全是符合C++標準的。雖然大家也必須承認window2000系統(tǒng)下對C++異常處理模型的這種擴展確實是一個很 不錯的完善,極大得提高了程序的安全性。

為什么要用catch(…)這個東東?
程序員朋友們也許會說,這還有問嗎?這篇文章的一開始不就講到了嗎?catch(…)能夠捕獲多種數(shù)據(jù)類型的異常對象,所以它提供給程序員一種對異常 對象更好的控制手段,使開發(fā)的軟件系統(tǒng)有很好的可靠性。因此一個比較有經(jīng)驗的程序員通常會這樣組織編寫它的代碼模塊,如下:

復(fù)制代碼 代碼如下:

 void Func()
{
try
{
// 這里的程序代碼完成真正復(fù)雜的計算工作,這些代碼在執(zhí)行過程中
// 有可能拋出DataType1、DataType2和DataType3類型的異常對象。
}
catch(DataType1& d1)
{
}
catch(DataType2& d2)
{
}
catch(DataType3& d3)
{
}
// 注意上面try block中可能拋出的DataType1、DataType2和DataType3三
// 種類型的異常對象在前面都已經(jīng)有對應(yīng)的catch block來處理。但為什么
// 還要在最后再定義一個catch(…) block呢?這就是為了有更好的安全性和
// 可靠性,避免上面的try block拋出了其它未考慮到的異常對象時導(dǎo)致的程
// 序出現(xiàn)意外崩潰的嚴重后果,而且這在用VC開發(fā)的系統(tǒng)上更特別有效,因
// 為catch(…)能捕獲系統(tǒng)出現(xiàn)的異常,而系統(tǒng)異常往往令程序員頭痛了,現(xiàn)
// 在系統(tǒng)一般都比較復(fù)雜,而且由很多人共同開發(fā),一不小心就會導(dǎo)致一個
// 指針變量指向了其它非法區(qū)域,結(jié)果意外災(zāi)難不幸發(fā)生了。catch(…)為這種
// 潛在的隱患提供了一種有效的補救措施。
catch(…)
{
}
}

還有,特別是VC程序員為了使開發(fā)的系統(tǒng)有更好的可靠性,往往在應(yīng)用程序的入口函數(shù)中(如MFC框架的開發(fā)環(huán)境下 CXXXApp::InitInstance())和工作線程的入口函數(shù)中加上一個頂層的trycatch塊,并且使用catch(…)來捕獲一切所有的 異常,如下:
復(fù)制代碼 代碼如下:

 BOOL CXXXApp::InitInstance()
{
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// 注意這里有一個頂層的trycatch塊,并且使用catch(…)來捕獲一切所有的異常
try
{
CXXXDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
}
catch(…)
{
// dump出系統(tǒng)的一些重要信息,并通知管理員查找出現(xiàn)意外異常的原因。
// 同時想辦法恢復(fù)系統(tǒng),例如說重新啟動應(yīng)用程序等
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}

通過上面的例程和分析可以得出,由于catch(…)能夠捕獲所有數(shù)據(jù)類型的異常對象,所以在恰當?shù)牡胤绞褂胏atch(…)確實可以使軟件系統(tǒng)有著更 好的可靠性。這確實是大家使用catch(…)這個東東最好的理由。但不要誤會的是,在C++異常處理模型中,不只有catch(…)方法能夠捕獲幾乎所 有類型的異常對象.

相關(guān)文章

  • C++使用ffmpeg實現(xiàn)rtsp取流的代碼

    C++使用ffmpeg實現(xiàn)rtsp取流的代碼

    這篇文章主要介紹了C++使用ffmpeg實現(xiàn)rtsp取流,文章介紹了ffmepg采用rtsp取流流程圖,CMakeLists.txt編寫方法,通過示例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-04-04
  • Qt?事件處理機制的深入理解

    Qt?事件處理機制的深入理解

    本文主要介紹了Qt?事件處理機制的深入理解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04
  • 詳解C++編程中標記語句與復(fù)合語句的寫法

    詳解C++編程中標記語句與復(fù)合語句的寫法

    這篇文章主要介紹了C++編程中標記語句與復(fù)合語句的寫法,是C++入門學習中的基礎(chǔ)知識,需要的朋友可以參考下
    2016-01-01
  • C語言實現(xiàn)24點問題詳解

    C語言實現(xiàn)24點問題詳解

    24點問題就是在屏幕上輸入1?10范圍內(nèi)的4個整數(shù)(可以有重復(fù)),對它們進行加、減、乘、除四則運算后(可以任意的加括號限定計算的優(yōu)先級),尋找計算結(jié)果等于24的表達式。本文將通過C語言實現(xiàn)24點問題的求解,需要的可以參考一下
    2021-12-12
  • C++ 實現(xiàn)即時通信的示例代碼(直接運行)

    C++ 實現(xiàn)即時通信的示例代碼(直接運行)

    本文主要介紹了C++ 實現(xiàn)即時通信的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • C/C++中的typedef和#define詳解

    C/C++中的typedef和#define詳解

    這篇文章主要介紹了C/C++中的typedef和#define詳解的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • C++函數(shù)的嵌套調(diào)用和遞歸調(diào)用學習教程

    C++函數(shù)的嵌套調(diào)用和遞歸調(diào)用學習教程

    這篇文章主要介紹了C++函數(shù)的嵌套調(diào)用和遞歸調(diào)用學習教程,是C++入門學習中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • C語言中堆空間的生成與釋放詳解

    C語言中堆空間的生成與釋放詳解

    以下是對C語言中堆空間的生成與釋放進行了詳細的分析介紹,需要的朋友可以過來參考下
    2013-08-08
  • 解析鴻蒙輕內(nèi)核靜態(tài)內(nèi)存的使用

    解析鴻蒙輕內(nèi)核靜態(tài)內(nèi)存的使用

    摘要:靜態(tài)內(nèi)存實質(zhì)上是一個靜態(tài)數(shù)組,靜態(tài)內(nèi)存池內(nèi)的塊大小在初始化時設(shè)定,初始化后塊大小不可變更。靜態(tài)內(nèi)存池由一個控制塊和若干相同大小的內(nèi)存塊構(gòu)成。控制塊位于內(nèi)存池頭部,用于內(nèi)存塊管理。內(nèi)存塊的申請和釋放以塊大小為粒度
    2021-06-06
  • 怎么鎖定鼠標的示例代碼分享

    怎么鎖定鼠標的示例代碼分享

    使用代碼怎么才能鎖定鼠標?這個功能很簡單只要一個ClipCursor()就可以搞定,需要的朋友可以參考下
    2014-01-01

最新評論