C/C++語言新增“函式過載”功能簡單介紹和使用方法

北亞資料恢復發表於2019-04-12

“函式過載”指的是可以有多個同名的函式,因此 名稱進行了過載。這兩個術語指的是同一回事,但我們通常使用函式過載。可以透過函式過載來設計• 系列函式——它們完成相同的工作,但使用不同的引數列表。

過載函式就像是有多種含義的動詞。例如, Piggy 小姐可以在棒球場為家鄉球隊助威( root , 也可以在地裡種植( root )菌類作物。根據上下文可以知道在每一種情況下, root 的含義是什麼。同樣, C++ 使用上下文來確定要使用的過載函式版本。

函式過載的關鍵是函式的引數列表 ——也稱為函式特徵標 (ftmction signature). 如果兩個函式的引數數目和型別相同,同時引數的排列順序也相同,則它們的特徵標相同,而變數名是無關緊要的。 C++ 允定義名稱相同的函式,條件是它們的特徵標不同。如果引數數目和 / 或引數型別不同,則特徵標也不同。例如,可以定義一組原型如下的 print() 函式:

Void print(const char * str, int width) ; // #1
Void print(double d, int width);   // #2
Void print(long 1, int width);    // #3 
Void print(int i, int width);     // #4 frombyte
Void print(const char *str);     // #5


使用 pnnt() 函式時,編譯器將根據所採取的用法使用有相應特徵標的原型 :

print(” Pancakes", 15);   //use #1
print(” syrup");    //use #2
print(” 1999.0,10");    //use #3
print(” 1999,12");    //use #4
print(” 1999L,15");    //use #5 frombyte.com


 

例如, print( Pancakes ”, 15) 使用一個字串和一個整數作為引數,這與 #1 原型匹配。 , 使用被 過載的函式時,需要在函式呼叫中使用正確的引數型別。例如,對於下面的語句 :

Unsigned int year =3210;
print (year, 6);   // ambiguous call


Print () 呼叫與哪個原型匹配呢?它不與任阿原型匹配!沒有 匹配的圓形並不會自 動停止使用其中的某 個函式, 因為 C++ 將嘗試使用標準型別轉換強制進行匹配。如果 #2 原型是 print() 唯一的原型,則函式呼叫 print(year 6) 將把 year 轉換為 double 型別。但在上面的程式碼中,有 3 個將數字作為第一個引數的原型,因 此有 3 轉換 year 的方式。在這種情況下, C++ 將拒絕這種函式呼叫,並將其視為錯誤。

一些 看起來彼此不同的特徵標是不能共存的。例如,請看下面的兩個原型:

duble cube (double x);
duble cube (double & x);


您可 能認為可以在 處使用函式重 , 因為它們的特徵標看起來不同。然而,請從編譯器的角度來 考慮這個問 題。假設有下面這樣的程式碼:

cout
.<< cube(x);


引數 X double x 原型和 double &x 原型都匹配,因此編譯器無法確定究竟應使用哪個原型。為避免 這種混亂, 編譯器在檢査函式特徵標時,將把型別引用和型別本身視為同一個特徵標。 匹配 函式時,並不區分 const 和非 const 變數。請看下面的原型:

Void dribble(char * bits);
Void dribble (const char *cbits);
Void dabble(char * bits);
Void drivel(const char * bits);


下面 列出了各種函式呼叫對應的原型 :

Const char p1[20]="How’s the weather?";
Char p2[20]="How's business?";
Dribble(p1);  // dribble(const char *); 
Dribble(p2);  // dribble(char *);
Dabble(p1);  // no match 
Dabble(p2);  // dabble(char *);
Drivel(p1);  // drivel(const char *);frombyte.com 
Drivel(p2);  // drivel(const char *);


drib ble() 函式有兩個原型,一個用於 const 指標,另一個用於常規指標,編譯器將根據實參是否為 const 來決定使 用哪個原型。 dribble() 函式只與帶非 const 引數的呼叫匹配,而 drivel() 函式可以與帶 const 或非 const 引數的呼叫匹配。 drivel ◦和 dabble() 之所以在行為上有這種差別,主要是由於將非 const 值賦給 const 變數是合法的,但反之則是非法的。

請記住,是特徵標,而不是函式型別使得可以對函式進行過載。例如,下面的兩個宣告是互斥的:

long gronk(int n, float m); // same signatures,
double gronk(int n, float m); // hence not allowed


因此, C++ 不允許以這種方式過載 gronk() 。返回型別可以不同,但特徵標也必須不同:

long gronk(int n; float m); // different signatures,
double gronk(float n# float m); // hence allowed


 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31380569/viewspace-2641195/,如需轉載,請註明出處,否則將追究法律責任。

相關文章