今天看到師兄寫的證書庫代碼,看到了一個很奇怪的東東,父類里有一個不是虛函數的函數,這個函數在子類中被重新寫了一遍,函數名,參數列表,返回值都一樣,就是在參數列表中的默認值給的不太一樣。我覺得太詭異了。加上以前c++的重寫和重載之類的概念也好長時間沒弄,糊涂了。真不知道這個四不像是什么了。在網上翻了一些文檔,發現這篇寫的非常完整,而且和我想的也一樣。其實師兄的這種寫法是非常ugly的。如果出現這種子類中完全重新寫了父類的函數,那么父類就應該將這個函數設為virtul的才對。當然如果沒有設置,編譯也不會出錯,這種情況下,會出現hide隱藏。隱藏(hide):指的是派生類的成員函數隱藏了基類函數的成員函數.隱藏一詞可以這么理解:在調用一個類的成員函數的時候,編譯器會沿著類的繼承鏈逐級的向上查找函數的定義,如果找到了那么就停止查找了,所以如果一個派生類和一個基類都有同一個同名(暫且不論參數是否相同)的函數,而編譯器最終選擇了在派生類中的函數,那么我們就說這個派生類的成員函數"隱藏"了基類的成員函數,也就是說它阻止了編譯器繼續向上查找函數的定義。而overload重載與繼承根本就沒關系,說的是同一個作用域中,相同類名,不同參數列表的現象。
轉載的原文見下面:
C++是一門magic的語言,很多機制復雜得讓人頭疼,但是這種迷宮競走的狀態讓人精力十足,我發誓了,不搞明白不罷休,同時也希望得到高手們的指點和幫助~
override 函數名和參數類型以及返回類型必須相同,即簽名都是一致的——或者叫相貌和衣服都是一樣的,一般用在繼承過程中。(高手判斷一下,除了實現細節,其他的是不是什么都應該相同?所以叫做“重寫”——《C++編程思想》上是這么翻譯的。)
overload 函數名必須相同,簽名必須不同(參數個數,順序,類型),返回類型可以不同,用在同一個類中,在編譯時候確定。
以下是轉載的內容:
override 是指在不同作用域中,多個函數原型完全一樣,而實現卻不同的函數。在C++中,經常發生在類的繼承中。當基類中的某個方法是virtual或pure virtual函數時
(當然訪問權限必須是public或protected,因為從C++設計思想上來講private的函數不會是virtual的!!!這個請問一下,是不是這樣的??),
其子類中對該方法的重新實現就屬于override(重寫)。
使用時,可以通過基類的指針或者引用所指向的具體對象來確定調用的是哪個方法,從而實現函數的多態。
(函數的多態?C++中實現多態性的手段之一嗎?還有多少其他的手段??)
對于基類中的非virtual類型的成員函數,若其子類中也聲明了與該函數名稱相同的函數,那么基類中的該函數(也許是一系列函數,如果該函數在基類中有重載的話)將被隱藏,可以通過域解析操作符來調用。不過按照C++的設計思想來說呢,基類中的非virtual類型的成員函數,是不需要在子類中進行修改的,所以如果在子類中出現了這種隱藏的情況,說明應該將基類中的該函數改成virtual類型的,然后就是override了!
overload則是指在相同作用域中,多個函數具有相同的名字,但參數的數目和類型各不相同(當然相同數目和類型,如果順序不同也是可以的),因為函數重載的機制是在C++中函數的簽名與其參數有關,而不像C中,只與函數名有關。
總之,override與overload的一個最大的區別就是作用域不同,以及函數原型是否相同.
override: 覆蓋是子類重寫父類的虛方法的一種形式。
overload: 重載是值允許存在重名的多個方法。而這些函數的參數列表不同(或者是參數
的個數不同、或者是參數的類型不同或者兩者都不同)。
重載(overload 與多態的概念無關) :因為是在編譯階段就確定的。
只有在與運行階段確定的才稱為面向對象的多態性。即override
面向對象的幾個基本概念
多態:目的實現接口重用
繼承:實現代碼重用。
封裝:實現代碼的模塊化.
override 表示重寫,用于繼承類對基類中虛成員的實現
overload 表示重載,用于同一個類中同名方法不同參數(包括類型不同或個數不同)的實現