重載(overload):是指編寫一個與已知函數同名但是參數表不同的函數。重載主要屬于靜态編聯範疇,是在編譯期就完成位址的配置設定。
普通成員函數的重載主要分成三部分:
(1)在一個類中說明重載。
如 show(int a,char b);//在編譯期經過編譯器修飾後函數名會變成int_char_show
show(char* c,double d);//在編譯期經過編譯器修飾後函數名會變成char_double_show
(2)在基類中聲明一個函數,在子類中重載這個函數(未聲明virtual關鍵字)(還有一種說法是隐藏,但我認為可以簡單的認為是一種特殊的重載更确切,不考慮這個兩個函數具有相同的參數),經過編譯期之後,有三種編譯區分的方法:
1.根據參數特征進行區分。
如 Base: show(int ,int );
Derived: show(int ,float);
這兩個函數不是一個函數,編譯器可以區分
2.根據“::”作用域符進行區分。編譯器進行編譯時,可根據不同的作用域進行區分重載函數。
如 Base::show( );
Derived::show( );
3.根據類對象進行區分調用哪一個重載函數。
如 Base b; b.show( );
Derived d; d.show( );
由上可知,重載隻是一種語言特性,與多态無關,與面向對象無關。
覆寫(override):是指派生類重寫基類的虛函數,重寫的函數必須具有一緻的參數表和傳回值。覆寫是一種動态編聯。在運作期進行确定所調用的函數位址。
覆寫是與多态密切相關的一種機制,與面向對象有關。
以下通過一個程式來說明重載與覆寫:
#include<iostream>
using namespace std;
class A
{
public:
A(int data = 0):m_data(data){}
virtual int doGetData()
{
return m_data;
}
int GetData()
{
return doGetData();
}
private:
int m_data;
};
class B:public A
{
public:
B(int data = 1):m_data(data){}
int doGetData()
{
return m_data;
}
private:
int m_data;
};
class C:public B
{
public:
C(int data=2):m_data(data){}
private:
int m_data;
};
int main(int argc, char* argv[])
{
C c(10);
cout<<c.GetData()<<endl;
cout<<c.A::GetData()<<endl;
cout<<c.B::doGetData()<<endl;//結果為1,理由同上。
cout<<c.C::GetData()<<endl;//結果為1 ,理由同上。
cout<<c.doGetData()<<endl;//由于C類中未定義虛函數doGetData()的接口,是以會調用父類的接口。結果為1.
cout<<c.A::doGetData()<<endl;//c.A::doGetData(),C類對象會直接調用A類的作用域内的記憶體空間,直接調用A的doGetData(),結果為0.
cout<<c.C::doGetData()<<endl;//因為C類為重定義該接口,是以調用B類的doGetd(),而B類的doGetData()傳回B::m_data,故輸出為1.
return 0;
}