本節書摘來自異步社群出版社《c++程式設計慣用法——進階程式員常用方法和技巧》一書中的第2章,第2.6節,作者: 【美】robert b. murray ,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。
c++中允許使用者寫出這樣的代碼:使用不同(個數或類型)的參數來調用(似乎是)同一個函數:
(當然,這些函數都應該對它們的參數有着同樣的抽象行為。)在c++中有三種方法可以這麼做:函數重載、使用有預設值的參數以及使用省略符。對于在同一個函數名中同時使用這三種方法中的多種所出現的結果,c++語言規則有着明确的定義。不過它們比較難以掌握,并且還容易讓人覺得驚奇。即使我們能夠很好地了解它們,那些維護我們代碼的人也可能不一定能夠完全掌握它們。對于同一個名字來說,我們應該對它選擇一種方案并且一直堅持使用這種方法。
省略符隻應該用在類似于printf這樣的需要無限(或近似無限)個重載版本的函數中。在使用了省略符的函數中并沒有對那些不定參數的類型進行編譯期的類型檢測,在函數内部我們還必須使用定義于頭檔案stdarg.h中的充滿魔幻色彩的宏[4]來獲得那些不定參數。如果函數沒有正确獲得該參數,那麼函數的傳回值就将無法确定。
假設我們已經去除了省略符,在使用預設值和重載之間的選擇通常都很容易。使用預設值可以讓我們使用多種不同的方法來同一個函數;使用重載則适用于需要調用不同的函數這種場合之下。
如果這兩者之間有一個是另外一個的簡化方式,并且同一個實作可以用在這兩種場合之下,那麼我們最好選擇使用帶預設值的方式。例如,我們有一個類string,它的構造函數帶有一個const char*的參數,但是我們又希望它有一個預設的構造函數。為了簡便,我們可以使用一個帶預設值的參數:
當多個事物在概念上相似,但實作形式又不一緻時,我們應該選擇使用重載:
上面三個print在概念上來說是一樣的,但它們的實作方法不一樣,是以我們必須對它們使用重載。
當我們為指針參數提供預設值時,下面這個小的文法陷阱就很容易出現:
編譯器會将=當作一個單獨的token來處理,這樣就将造成一個文法錯誤。我們應該在後面增加一個空格:
對于有着預設值的引用對象來說,編譯器也是同樣處理的: