成員函數被重載的特征: //////////////////基類中
(1)相同的范圍(在同一個類中);
(2)函數名字相同;
(3)參數不同;
(4)virtual關鍵字可有可無。
覆蓋是指派生類函數覆蓋基類函數,特征是: /////////////基類與子類的關系
(1)不同的范圍(分別位于派生類與基類);
(2)函數名字相同;
(3)參數相同;
(4)基類函數必須有virtual關鍵字。
“隱藏”是指派生類的函數屏蔽了與其同名的基類函數,規則如下: ////////子類中
(1)如果派生類的函數與基類的函數同名,但是參數不同。此時,不論有無virtual關鍵字,基類的函數將被隱藏(注意別與重載混淆)。
(2)如果派生類的函數與基類的函數同名,并且參數也相同,但是基類函數沒有virtual關鍵字。此時,基類的函數被隱藏(注意別與覆蓋混淆)。
#include
class B {
public:
void mf(){cout<<"1 ";};
};
class D: public B {
public:
void mf(){cout<<"2 ";};
};
main(){
D x;
B *pB = &x;
pB->mf();
D *pD = &x;
pD->mf();
//B bb;
// bb.mf();
}
兩種情況下調用的都是對象x的成員函數mf,因為兩種情況下都是相同的函數和相同的對象,所以行為會相同,對嗎?
對,會相同。但,也許不會相同。特別是,如果mf是非虛函數而D又定義了自己的mf版本,行為就不會相同.
1)當類B中有虛函數mf()時,類D中沒有重寫此函數時,結果為:1 1。 一般的繼承
2)當類B中有虛函數mf()時,類D中重寫此函數時,結果為:2 2。 派生類函數覆蓋基類函數
3)當類B中有非虛函數mf()時,類D中沒有重寫此函數時,結果為:1 1。 一般的繼承
4)當類B中有非虛函數mf()時,類D中重寫此函數時,結果為:1 2。 類D中的函數隱藏了從基類B中繼承下來的函數
5)當類B中有虛或非虛函數mf()時,類D中有與此函數同名但時參數不同的函數時,從基類繼承而來的函數也被隱藏!
------------------------------------------------------------------------------------------
多重繼承的成員調用:
cbase
CBase1:public CBase
CBase2:public CBase
CDervied:public CBase1,CBase2
1)當cbase1與cbase2不是虛繼承的時:dervied不能訪問基類繼承而來(即共有的)的任何成員,不能識別。
2)當cbase1與cbase2是虛繼承的時,dervied可以訪問cbase中沒有1和2重新定義的成員,也能訪問只被1或只被2重新定義的成員,這是調用1或2中的成員,當dervied中有重寫時,調用derived中重新定義的成員。(共有)
:保證我們在不考慮繼承而來的隱藏成員時,能夠識別該調用那個類中的!則編譯器也能識別!
3)
在調用變量的時候,要指出時屬于那個類。