天天看點

《C++面向對象高效程式設計(第2版)》——2.21 確定抽象的可靠性——類不變式和斷言define PRE_CONDITION(condition) assert(condition)define POST_CONDITION(condition) assert(condition)`

本節書摘來自異步社群出版社《c++面向對象高效程式設計(第2版)》一書中的第2章,第2.21節,作者: 【美】kayshav dattatri,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

c++面向對象高效程式設計(第2版)

任何抽象都必須與客戶履行它的契約(contract)。當客戶使用類時,他希望類的對象像其釋出描述的那樣運作正常。另一方面,類的實作者必須千方百計地確定對象運作正常。但是,類隻有在客戶履行自己那部分契約後,才能正确行使它的職責。例如,類的成員函數可能要求傳入的參數為非零指針(non-zero pointer)。隻有滿足此前提條件,成員函數才能保證它的行為。是以,客戶必須履行一些義務。換言之,如果客戶履行了她那部分契約,對象的實作者必須尊重客戶那部分契約,并確定正當的行為。

在類和成員函數的文檔中說明契約,這個主意不錯。但是,把這些契約條件作為類的一部分實作代碼,在執行類實作時檢測契約條件,效果更好。這展現了斷言(assertion)的巨大價值所在。

通常,斷言是一個用于評估真假的表達式。如果表達式評估為假,則斷言失敗。例如,在tlaserdiscplayer類中,play成員函數會包含一個托盤關閉的斷言。稍後即将介紹它的文法。

進一步研究發現,在每個成員函數中(或甚至在一個成員函數的内部的多處)都包含一個斷言可能并不友善。每個類都會在對象中包含一些恒為真的條件,無論對象調用任何成員函數,這些條件都必須為真。這樣的條件稱為類不變式(class invariant)。顧名思義,在對象中這些條件恒為真。如果我們以某種方式給類添加這些條件,并保證每個成員函數的代碼都檢查這些條件,将會非常友善。

除這些類不變式之外,成員函數可能會包含其他條件,在執行代碼前必須保證這些條件為真。這些在操作開始被調用之前必須為真的條件,稱為前置條件(precondition)。

c++:

在c和c++中,斷言已經使用很長一段時間。所有的c和c++編譯器都支援assert宏。該宏接受一個表達式,而且必須判斷表達式的真假。倘若表達式判斷為真,則繼續執行;倘若表達式為假,則程式停止,并顯示錯誤消息表明斷言失敗。消息中包含檔案名,違規的語句源代碼行号。這是最簡單的(且唯一可用的)斷言形式。play成員函數的斷言代碼如下:

如果需要,可以在這些宏中添加消息,當斷言失敗時列印消息。

繼續閱讀