一舶替、重載(overload)
指函數(shù)名相同嫂拴,但是它的參數(shù)表列個數(shù)或順序播揪,類型不同。但是不能靠返回類型來判斷筒狠。
(1)相同的范圍(在同一個作用域中) 猪狈;
(2)函數(shù)名字相同;
(3)參數(shù)不同辩恼;
(4)virtual 關(guān)鍵字可有可無雇庙。
(5)返回值可以不同;
二灶伊、重寫(也稱為覆蓋 override)
是指派生類重新定義基類的虛函數(shù)疆前,特征是:
(1)不在同一個作用域(分別位于派生類與基類) ;
(2)函數(shù)名字相同聘萨;
(3)參數(shù)相同竹椒;
(4)基類函數(shù)必須有 virtual 關(guān)鍵字,不能有 static 米辐。
(5)返回值相同(或是協(xié)變)胸完,否則報錯书释;<—-協(xié)變這個概念我也是第一次才知道…
(6)重寫函數(shù)的訪問修飾符可以不同。盡管 virtual 是 private 的舶吗,派生類中重寫改寫為 public,protected 也是可以的
三、重定義(也成隱藏)
(1)不在同一個作用域(分別位于派生類與基類) 择膝;
(2)函數(shù)名字相同誓琼;
(3)返回值可以不同;
(4)參數(shù)不同肴捉。此時腹侣,不論有無 virtual 關(guān)鍵字,基類的函數(shù)將被隱藏(注意別與重載以及覆蓋混淆) 齿穗。
(5)參數(shù)相同傲隶,但是基類函數(shù)沒有 virtual關(guān)鍵字。此時窃页,基類的函數(shù)被隱藏(注意別與覆蓋混淆) 跺株。
通過這里可以看出:
1.Base類中的第二個函數(shù)a是對第一個的重載
2.Derived類中的函數(shù)b是對Base類中函數(shù)b的重寫,即使用了虛函數(shù)特性脖卖。
3.Derived類中的函數(shù)a是對Base淚中函數(shù)a的隱藏乒省,即重定義了。
4.pb指針是一個指向Base類型的指針畦木,但是它實(shí)際指向了一個Derived的空間袖扛,這里對pd調(diào)用函數(shù)的處理(多態(tài)性)取決于是否重寫(虛函數(shù)特性)了函數(shù),若沒有十籍,則依然調(diào)用基類蛆封。
5.只有在通過基類指針或基類引用 間接指向派生類類型時多態(tài)性才會起作用。
6.因?yàn)锽ase類的函數(shù)c沒有定義為virtual虛函數(shù)勾栗,所以Derived類的函數(shù)c是對Base::c()的重定義惨篱。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (2)
重載overload:是函數(shù)名相同,參數(shù)列表不同重載只是在類的內(nèi)部存在围俘。但是不能靠返回類型來判斷妒蛇。
重寫override:也叫做覆蓋。子類重新定義父類中有相同名稱和參數(shù)的虛函數(shù)楷拳。函數(shù)特征相同绣夺。但是具體實(shí)現(xiàn)不同,主要是在繼承關(guān)系中出現(xiàn)的?欢揖。
重寫需要注意:
1 被重寫的函數(shù)不能是static的陶耍。必須是virtual的
2重寫函數(shù)必須有相同的類型,名稱和參數(shù)列表
3重寫函數(shù)的訪問修飾符可以不同她混。盡管virtual是private的烈钞,派生類中重寫改寫為public,protected也是可以的
重定義 (redefining)也叫做隱藏:
子類重新定義父類中有相同名稱的非虛函數(shù)( 參數(shù)列表可以不同 ) 泊碑。
如果一個類,存在和父類相同的函數(shù)毯欣,那么馒过,這個類將會覆蓋其父類的方法,除非你在調(diào)用的時候酗钞,強(qiáng)制轉(zhuǎn)換為父類類型腹忽,否則試圖對子類和父類做類似重載的調(diào)用是不能成功的。
class Base {
private:
virtualvoid display() { cout<<"Base display()"<
void say(){ cout<<"Base say()"<
public:
void exec(){ display(); say(); }
void f1(string a) { cout<<"Base f1(string)"<
void f1(int a) { cout<<"Base f1(int)"<
};
class DeriveA:public Base{
public:
void display() { cout<<"DeriveA display()"<//override砚作,基類中display為虛函數(shù)窘奏,故此處為重寫
void f1(int a,int b) { cout<<"DeriveA f1(int,int)"<重定義
void say() { cout<<"DeriveA say()"<
};
class DeriveB:public Base
{
public:
void f1(int a) { cout<<"DeriveB f1(int)"<
};
int main(){
DeriveA a;
Base *b=&a;
b->exec(); //display():version of DeriveA call(polymorphism)?//say():version of Base called(allways )
b里邊的函數(shù)display被A類覆蓋,但是say還是自己的葫录。
a.exec(); //same result as last statement
a.say();
DeriveB c;
c.f1(1); //version of DeriveB called
}
執(zhí)行結(jié)果:
綜上所述着裹,總結(jié)如下:
1 成員函數(shù)重載特征:
a 相同的范圍(在同一個類中)
b 函數(shù)名字相同
c 參數(shù)不同
d virtual關(guān)鍵字可有可無
2 重寫(覆蓋)是指派生類函數(shù)覆蓋基類函數(shù),特征是:
a 不同的范圍米同,分別位于基類和派生類中
b 函數(shù)的名字相同
c 參數(shù)相同
d 基類函數(shù)必須有virtual關(guān)鍵字
3 重定義(隱藏)是指派生類的函數(shù)屏蔽了與其同名的基類函數(shù)骇扇,規(guī)則如下:
a 如果派生類的函數(shù)和基類的函數(shù)同名,但是參數(shù)不同面粮,此時匠题,不管有無virtual,基類的函數(shù)被隱藏但金。
b 如果派生類的函數(shù)與基類的函數(shù)同名韭山,并且參數(shù)也相同,但是基類函數(shù)沒有vitual關(guān)鍵字冷溃,此時钱磅,基類的函數(shù)被隱藏。