異常機(jī)制的使用
根據(jù)上述規(guī)則,典型的try-catch的結(jié)構(gòu)示例如下:本文引用地址:http://www.ex-cimer.com/article/202581.htm
細(xì)心的讀者也許會(huì)發(fā)現(xiàn),上面例子中是通過(guò)引用來(lái)捕獲類的對(duì)象。當(dāng)異常對(duì)象類型為某個(gè)類時(shí),有3種方式傳遞到catch子句里:指針、傳值和引用。也許大家首先想到的是指針,指針的確是效率很高的工具,而且不涉及到對(duì)象拷貝。但不要忘了,前面的規(guī)則15-0-2中明確指出,拋出的異常對(duì)象不應(yīng)該是指針類型。而對(duì)于傳值和引用,在MISRA C++中給出的規(guī)定是:通過(guò)引用捕獲異常。
規(guī)則15-3-5(強(qiáng)制):若異常對(duì)象為類的對(duì)象時(shí),應(yīng)該通過(guò)引用來(lái)捕獲。
通過(guò)值傳遞,不但會(huì)增加拷貝對(duì)象的開(kāi)銷,而且還會(huì)出現(xiàn)“退化”問(wèn)題。所謂“退化”是指:如果異常對(duì)象是一個(gè)派生類對(duì)象,但被作為基類捕獲,那么只有基類的函數(shù)(包括虛函數(shù))能被調(diào)用,派生類中增加的數(shù)據(jù)成員都不能被訪問(wèn)。通過(guò)引用捕獲則沒(méi)有這個(gè)問(wèn)題。下面的例子具體地說(shuō)明了“退化”問(wèn)題:
鑒于類的構(gòu)造函數(shù)和析構(gòu)函數(shù)的特殊性,還有兩點(diǎn)需要注意。
規(guī)則15-3-3(強(qiáng)制):如果類的構(gòu)造函數(shù)和析構(gòu)函數(shù)是function-try-block結(jié)構(gòu)的,在catch處理程序中不能引用該類或其基類的非靜態(tài)成員。
這種行為的后果是不定的。比如說(shuō),當(dāng)構(gòu)造對(duì)象分配內(nèi)存時(shí)拋出了異常,這時(shí)該對(duì)象本身還不存在,訪問(wèn)其成員也就出錯(cuò)。相反,在析構(gòu)函數(shù)里,可能在異常處理程序執(zhí)行前該對(duì)象已被成功銷毀了,也就無(wú)從訪問(wèn)其成員了。而類的靜態(tài)成員則沒(méi)有上述問(wèn)題。
規(guī)則15-5-1(強(qiáng)制)。類的析構(gòu)函數(shù)退出后不能還有未處理的異常。
當(dāng)異常拋出時(shí),會(huì)進(jìn)行棧展開(kāi)。如果在某個(gè)析構(gòu)過(guò)程中引發(fā)沒(méi)有被處理的異常,程序?qū)?huì)以不定的方式終止。析構(gòu)函數(shù)拋出異常的問(wèn)題在很多C++的書中都有討論,概括來(lái)說(shuō):析構(gòu)函數(shù)應(yīng)盡可能地避免拋出異常,如果的確無(wú)法避免,則析構(gòu)函數(shù)自己應(yīng)該包含處理所有可能拋出的異常的代碼。
4 小 結(jié)
異常機(jī)制是C++嶄新而高級(jí)的特性之一。與其他C++特性一樣,C++標(biāo)準(zhǔn)并沒(méi)有規(guī)定應(yīng)該如何來(lái)實(shí)現(xiàn)異常機(jī)制,這依賴于具體的編譯器。異常機(jī)制是有代價(jià)的,它會(huì)增加代碼大小和運(yùn)行開(kāi)銷。以VC++為例,異常處理是通過(guò)在函數(shù)調(diào)用棧里增加許多相關(guān)的數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn)的,感興趣的讀者可以查看相關(guān)資料,這里不再進(jìn)一步討論;而且異常處理是在操作系統(tǒng)的協(xié)助下,由C++編譯器和運(yùn)行時(shí)異常處理庫(kù)共同完成的。如何合理地使用異常機(jī)制來(lái)提高程序的健壯性,MISRA C++給出了一些規(guī)范,但具體還需要程序員反復(fù)斟酌,甚至需要多次實(shí)驗(yàn)。至此,關(guān)于MISRA-C++:2008的學(xué)習(xí)暫告一段落。
在這4期的講座中,我們主要討論了C++對(duì)于C新增的特性,列舉和解釋了其中有代表性的規(guī)則,且盡量使每篇文章都能涵蓋C++的一個(gè)重要特性。有些例子是在我們理解的基礎(chǔ)上加的,可能存在著錯(cuò)誤或偏差,歡迎大家和我們共同討論。通過(guò)這4期介紹,希望大家能夠意識(shí)到:C++對(duì)于C并不是簡(jiǎn)單的語(yǔ)言的改進(jìn),C++面向?qū)ο蟮乃枷霃母旧嫌绊懥塑浖募軜?gòu)。
可以預(yù)見(jiàn),隨著嵌入式產(chǎn)業(yè)的飛速發(fā)展,在嵌入式領(lǐng)域C++將會(huì)有輝煌的前景。對(duì)C++進(jìn)行改造,使其適用于嵌入式環(huán)境,提高其可靠性,對(duì)于推動(dòng)C++在嵌入式領(lǐng)域的應(yīng)用是很重要的。MISRA-C已經(jīng)在嵌入式C語(yǔ)言上取得了很大的成功,成為行業(yè)普遍認(rèn)同和遵循的規(guī)范。我們希望MISRA-C++也能和MISRA-C一樣,推動(dòng)C++在嵌入式領(lǐng)域的規(guī)范化。
評(píng)論