我理解到的app
隱藏,子類父類同名函數,參數不同就是隱藏(在子類中父類函數爲不可見),即ide
class Fruit { public: void priName(int s) { cout<<"水果"<<endl; } }; class Apple :public Fruit { public: void priName(int a,int l) { cout<<"蘋果"<<endl; } }; int main(int argc, char *argv[]) { Apple* apple=new Apple; apple->priName(0); /*父類中的priName(int) 爲不可見 也就是隱藏 該處編譯器報錯,沒法找打匹配的函數,但在 Apple中可用using priName 解決訪問不了priName(int) */ return 0; }
參數相同時函數
class Fruit { public: void priName(int s) { cout<<"水果"<<endl; } }; class Apple :public Fruit { public: void priName(int a) { cout<<"蘋果"<<endl; } }; int main(int argc, char *argv[]) { Apple* apple=new Apple; apple->priName(0);//參數相同,調用子類函數, ////////////*****///// Fruit* apple1=new Apple; apple1->priName(0); /*若是帶有virtual 重寫了 父類函數 那麼調用 子類 即覆蓋(override) 若是未重寫 那麼就是調用父類函數,也就是未覆蓋, 若是不帶virtual 直接就是隱藏 父類,調用子類的函數 */ return 0; }
/*******************************************************/ui
重載(overload)即便一個類中參數不一樣的函數指針
/******************************************************************************/code
這幾個概念都有一個共同點:函數名稱相同,因此難免讓人混淆,大體的區別以下:對象
重載:必須在一個域中,函數名稱相同可是函數參數不一樣,重載的做用就是同一個函數有不一樣的行爲,所以不是在一個域中的函數是沒法構成重載的,這個是重載的重要特徵繼承
覆蓋:覆蓋指的是派生類的虛擬函數覆蓋了基類的同名且參數相同的函數,既然是和虛擬函數掛鉤,說明了這個是一個多態支持的特性,所謂的覆蓋指的是用基類對象的指針或者引用時訪問虛擬函數的時候會根據實際的類型決定所調用的函數,所以此時派生類的成員函數能夠"覆蓋"掉基類的成員函數.編譯器
注意惟有同名且參數相同還有帶有virtual關鍵字而且分別在派生類和基類的函數才能構成虛擬函數,這個也是派生類的重要特徵.it
並且,因爲是和多態掛鉤的,因此只有在使用類對象指針或者引用的時候才能使用上.
總之一句話:覆蓋函數都是虛函數,反之否則~~
隱藏:指的是派生類的成員函數隱藏了基類函數的成員函數.隱藏一詞能夠這麼理解:在調用一個類的成員函數的時候,編譯器會沿着類的繼承鏈逐級的向上查找函數的定義,若是找到了那麼就中止查找了,因此若是一個派生類和一個基類都有同一個同名(暫且不論參數是否相同)的函數,而編譯器最終選擇了在派生類中的函數,那麼咱們就說這個派生類的成員函數"隱藏"了基類的成員函數,也就是說它阻止了編譯器繼續向上查找函數的定義....
回到隱藏的定義中,前面已經說了有virtual關鍵字而且分別位於派生類和基類的同名,同參數函數構成覆蓋的關係,所以隱藏的關係只有以下的可能:
1)必須分別位於派生類和基類中
2)必須同名
3)參數不一樣的時候自己已經不構成覆蓋關係了,因此此時是不是virtual函數已經不重要了
當參數相同的時候就要看時候有virtual關鍵字了,有的話就是覆蓋關係,沒有的時候就是隱藏關係了