第4集C++的異常處理和面向?qū)ο蟮木o密關(guān)系

字號:

如果有人問起C++和C到底有那些本質(zhì)上的不同點(diǎn)?主人公阿愚當(dāng)然也會有自己的一份理解,他會毫不猶豫回答出:“與C相比,C++至少引入了兩項重要技術(shù),其一就是對面向?qū)ο蟮娜嬷С?;還有一項就是C++優(yōu)良的異常處理模型”。是的,這兩項技術(shù)對構(gòu)建出一個優(yōu)良的可靠復(fù)雜的軟件系統(tǒng)都太重要了??蛇@兩項技術(shù)之間又有何關(guān)系呢?非??陀^公正的說,它們之間的關(guān)系實在是太緊密了,兩者相互支持和依賴,是構(gòu)建優(yōu)良可靠復(fù)雜的軟件系統(tǒng)最不可缺乏的兩個東東。
    用對象來描述程序中出現(xiàn)的異常
    雖然前幾篇文章的內(nèi)容中列舉的一些小例子程序大多都是throw一些如int、double類型的異常,但程序員朋友都很熟悉,實際開發(fā)環(huán)境中所拋出的異常都是一個個代表抽象數(shù)據(jù)類型的對象,如C++標(biāo)準(zhǔn)庫中的std::exception(),MFC開發(fā)庫中Cexception等。用對象來描述的我們程序中的出現(xiàn)異常的類型和異常信息是C++異常處理模型中最閃光之處,而且這一特點(diǎn)一直沿用到j(luò)ava語言的異常處理模型中。
    為什么要用對象來描述程序中出現(xiàn)的異常呢?這樣做的優(yōu)勢何在?主人公阿愚不喜歡窮擺出什么大道理,還是老辦法,從具體的實例入手。由于異常有許許多多種類型,如有致命的錯誤、一般的錯誤、警告或其它事件通知等,而且不同類型的異常有不同的處理方法,有的異常是不可恢復(fù)的,而有的異常是可以恢復(fù)的(專業(yè)術(shù)語叫做“重入”吧!哈哈,主人公阿愚有時也會來點(diǎn)文縐縐的東西),所以程序員在開發(fā)系統(tǒng)時就必須考慮把各種可能出現(xiàn)的異常進(jìn)行分類,以便能夠分別處理。下面為一個應(yīng)用系統(tǒng)設(shè)計出一個對異常進(jìn)行分類的簡單例子,如下:
    從上面的異常分類來看,它有明顯的層次性和繼承性,這恰恰和面向?qū)ο蟮睦^承思想如出一轍,因此用對象來描述程序中出現(xiàn)的異常是再恰當(dāng)不過的了。而且可以利用面向?qū)ο蟮奶匦院芎玫膶Ξ惓_M(jìn)行分類處理,例如有這樣一個例子:
    void OpenFile(string f)
    {
    try
    {
    // 打開文件的操作,可能拋出FileOpenException
    }
    catch(FileOpenException& fe)
    {
    // 處理這個異常,如果這個異常可以很好的得以恢復(fù),那么處理完畢后函數(shù)
    // 正常返回;否則必須重新拋出這個異常,以供上層的調(diào)用函數(shù)來能再次處
    // 理這個異常對象
    int result = ReOpenFile(f);
    if (result == false) throw;
    }
    }
    void ReadFile(File f)
    {
    try
    {
    // 從文件中讀數(shù)據(jù),可能拋出FileReadException
    }
    catch(FileReadException& fe)
    {
    // 處理這個異常,如果這個異常可以很好的得以恢復(fù),那么處理完畢后函數(shù)
    // 正常返回;否則必須重新拋出這個異常,以供上層的調(diào)用函數(shù)來能再次處
    // 理這個異常對象
    int result = ReReadFile(f);
    if (result == false) throw;
    }
    }
    void WriteFile(File f)
    {
    try
    {
    // 往文件中寫數(shù)據(jù),可能拋出FileWriteException
    }
    catch(FileWriteException& fe)