本節書摘來自異步社群出版社《imperfect c++中文版》一書中的第2章,第2.2節,作者: 【美】martin d.carroll , margaret a.ellis,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。
c++代碼設計與重用
2.2 正規函數
對所有提供它們的類而言,某些函數應該具有相同的語義。考慮類rational的拷貝構造函數:
上面的操作将會構造一個rational對象,它的值等同于對象r的值(我們所說的值總是指抽象值)。我們認為,每個類的拷貝構造函數都應該具有這樣的語義,就是構造一個和它的參數等值的對象。盡管c++沒有—也不能—強制拷貝構造函數遵循這種限制,但每個設計良好的c++類都應該遵守這種限制。
如果在所有設計良好的類中,某個函數的語義都是相同的話,我們就稱這個函數為正規函數。c++中的正規函數有:
拷貝構造函數;
析構函數;
基本的指派運算符(指類t的指派運算符,它的唯一參數的類型是const t&或t);
相等運算符和不等運算符。
下面的類t顯式聲明了(上面)這些正規函數:
在這裡,我們将相等運算符和不等運算符聲明成全局函數。當然,它們也可以作為類t的成員函數。(bool類型是c++新增的類型,它有真和假兩種值,真值用新關鍵字true來表示,假值用新關鍵字false來表示。)
正規函數的語義如下:
建立一個t對象,它的(抽象)值和t對象的(抽象)值相等。
銷毀t對象。
用參數t的值給這個新對象指派,并傳回一個此對象的引用。
當且僅當tl和t2具有相同的值時,傳回true。
當且僅當tl和t2具有不同的值時,傳回true。
上面這些正規語義都是抽象的;當然,它們也就有許多種合理的底層實作方法。(實際上,對于operator= =和operator!=這兩個運算符,為了確定能夠準确無誤的實作,它們其中的一個是根據(通過調用)另一個的實作細節來實作的。)即使上面所給函數是由編譯器隐式生成的(構造函數,析構函數和指派運算符是可以由編譯器隐式生成的)1,或者是成員函數,而不是全局函數(雙目運算符往往實作成全局函數),這些語義還是成立的。
對所有設計良好的代碼,它們所有正規函數的語義都是相同的,是以,(嚴格說來)給函數的語義添加幫助文檔是沒有必要的。然而,一些過于謹慎的c++程式庫設計者為了確定使用者可以了解添加的正規函數,往往在很多地方添加了正規函數語義的幫助文檔,但這樣做的意義并不大。
1關于編譯器如何實作這3個函數,具體請參閱inside the c++object model,但有一規則就是:拷貝構造函數、析構函數和指派運算符這3個函數,要麼都由編譯器隐式生成,要麼都由使用者提供具體實作,具體參閱herb sutter在cuj的conversation.
本文僅用于學習和交流目的,不代表異步社群觀點。非商業轉載請注明作譯者、出處,并保留本文的原始連結。