這幾個概念都有一個共同點:函數名稱相同,所以不免讓人混淆,大致的區別如下:
重載(overload):
必須在一個域中,函數名稱相同但是函數參數不同,重載的作用就是同一個函數有不同的行為,因此不是在一個域中的函數是無法構成重載的,這個是重載的重要特征
覆蓋(override):
覆蓋指的是派生類的虛擬函數覆蓋了基類的同名且參數相同的函數,既然是和虛擬函數掛鉤,說明了這個是一個多態支持的特性,所謂的覆蓋指的是用基類對象的指針或者引用時訪問虛擬函數的時候會根據實際的類型決定所調用的函數,因此此時派生類的成員函數可以"覆蓋"掉基類的成員函數.
注意唯有同名且參數相同還有帶有virtual關鍵字並且分別在派生類和基類的函數才能構成虛擬函數,這個也是派生類的重要特征.
而且,由於是和多態掛鉤的,所以只有在使用類對象指針或者引用的時候才能使用上.
總之一句話:覆蓋函數都是虛函數,反之不然~~
隱藏(hide):
指的是派生類的成員函數隱藏了基類函數的成員函數.隱藏一詞可以這麼理解:在調用一個類的成員函數的時候,編譯器會沿著類的繼承鏈逐級的向上查找函數的定義,如果找到了那麼就停止查找了,所以如果一個派生類和一個基類都有同一個同名(暫且不論參數是否相同)的函數,而編譯器最終選擇了在派生類中的函數,那麼我們就說這個派生類的成員函數"隱藏"了基類的成員函數,也就是說它阻止了編譯器繼續向上查找函數的定義....
回到隱藏的定義中,前面已經說了有virtual關鍵字並且分別位於派生類和基類的同名,同參數函數構成覆蓋的關系,因此隱藏的關系只有如下的可能:
1)必須分別位於派生類和基類中
2)必須同名
3)參數不同的時候本身已經不構成覆蓋關系了,所以此時是否是virtual函數已經不重要了
當參數相同的時候就要看時候有virtual關鍵字了,有的話就是覆蓋關系,沒有的時候就是隱藏關系了
上面的解說大體把三者的區別給說清楚了,但是還有一些疑惑的地方,以下以代碼例子說明.
很多人分辨不清隱藏和覆蓋的區別,因為他們都是發生在基類和派生類之中的.但是它們之間最為重要的區別就是:
覆蓋的函數是多態的,是存在於vtbl之中的函數才能構成"覆蓋"的關系,而隱藏的函數都是一般的函數,不支持多態,在編譯階段就已經確定下來了.