C++中的函式過載、覆蓋與隱藏
在C++語言中,函式扮演著很重要的角色,不管面向過程設計,還是基於物件設計;不管是面向物件程式設計,還是基於泛型程式設計,函式都可以隨處而見。在談論C++中的函式過載、覆蓋和隱藏之前,先回顧下函式的基礎知識。
函式的宣告包括函式的返回值型別,函式名稱,引數列表(引數的型別、引數的個數、引數的順序)。例如,宣告一個兩個整數之和的函式,int iAdd(int iNum1,int iNum2);而函式的定義可以理解為對函式功能的詳盡而準確的解說,通俗點,就是實現函式“how to do?”的效能。兩個整數之和函式的定義如下:
-
<span style="font-weight: normal;"><span style="font-family:SimSun;font-size:10px;">int iAdd(int iNum1,int iNum2)
-
{
-
return (iNum1+iNum2);
-
}</span></span>
仔細觀察函式的宣告和定義,我們不難發現,函式的定義就是除掉函式聲明後面的分號,換之成大括號,在大括號裡面實現函式的功能。雖然在某些情況下,可以容許不對函式進行宣告,只需要對函式定義,就能呼叫函數了。但是,強烈建議養成先宣告函式,然後再定義函式,最後在呼叫函式的良好習慣。關於函式的基礎知識,暫時論述到這。
現在,進入本文的主題。函式過載(function overload),它是在同一可訪問區域內部宣告具有幾個不同引數列(引數的型別、引數的個數,引數的順序)的相同函式名稱的一種機制,函式的呼叫是根據不同的引數型別和最佳匹配原則確定最終使用那個函式。函式覆蓋(function override)是在派生類中完全一致性地聲明瞭父類中的函式,區別在於函式定義中的大括號之間的內容可以不同,並且該函式在父類中有關鍵字virtual標識;函式隱藏(function hide)是指在派生類中函式與父類函式完全一致,但是在父類中該函式沒有關鍵字virtual標識,或者是指在派生類中函式與父類的函式名相同,引數列表不一樣,父類中的該函式可有也可無關鍵字virtual標識。
函式過載的特徵:相同的範圍內(在同一個類中),函式的名稱相同,引數列表不同,virtual關鍵字可有可無;函式覆蓋的特徵:在不同的範圍內(父類與派生類),函式的名字相同,引數列表相同,父類函式必須有關鍵字virtual;函式隱藏的特徵:在不同範圍內(父類與派生類),函式的名字相同,引數列表相同,但是父類函式沒有關鍵字virtual或者,引數列表不相同,父類函式中virtual關鍵字可有可無。為了直觀地理解,請看下面的程式碼。
<span style="font-weight: normal;"><span style="font-family:SimSun;font-size:10px;">#include<iostream> using namespace std; class A { public: void print(int iNum) { cout<<"在類A中,引數型別是整型"<<endl; } void print(float fNum) { cout<<"在類A中,引數型別是單精度浮點型"<<endl; } virtual void print(void) { cout<<"在類A中,引數型別是空型別"<<endl; } }; class B:public A { public: void print( void) { cout<<"在類B中,引數型別是空型別"<<endl; } void print(int iNum) { cout<<"在類B中,引數型別是整型"<<endl; } }; int main() { A a; B b; //函式的過載 a.print(); a.print(1); a.print(1.0f); //函式的覆蓋 b.print(); //函式的隱藏 b.print(1); return 0; }</span></span>
執行結果是:
在類A中,引數型別是空型別
在類A中,引數型別是整型
在類A中,引數型別是單精度浮點型
在類B中,引數型別是空型別
在類B中,引數型別是整型
通過上述程式碼和執行的結果,簡明地知道了函式過載,覆蓋和隱藏。恰當裡利用這些特性,可以編寫出更加有效、清晰和精簡的程式碼。