過載的起源
自然語言中,乙個詞可以有許多不同的含義,即該詞被過載了。人們可以通過上下文來判斷該詞到底是哪種含義。「詞的過載」可以使語言更加簡練。例如「吃飯」的含義十分廣泛,人們沒有必要每次非得說清楚具體吃什麼不可。別迂腐得象孔已己,說茴香豆的茴字有四種寫法。
在c++程式中,可以將語義、功能相似的幾個函式用同乙個名字表示,即函式過載。這樣便於記憶,提高了函式的易用性,這是c++語言採用過載機制的乙個理由。例如示例8-1-1中的函式eatbeef,eatfish,eatchicken可以用同乙個函式名eat表示,用不同型別的引數加以區別。
void eatbeef(…); // 可以改為 void eat(beef …);
void eatfish(…); // 可以改為 void eat(fish …);
void eatchicken(…); // 可以改為 void eat(chicken …);
示例8-1-1 過載函式eat
c++語言採用過載機制的另乙個理由是:類的建構函式需要過載機制。因為c++規定建構函式與類同名(請參見第9章),建構函式只能有乙個名字。如果想用幾種不同的方法建立物件該怎麼辦?別無選擇,只能用過載機制來實現。所以類可以有多個同名的建構函式。
過載是如何實現的?
幾個同名的過載函式仍然是不同的函式,它們是如何區分的呢?我們自然想到函式介面的兩個要素:引數與返回值。
如果同名函式的引數不同(包括型別、順序不同),那麼容易區別出它們是不同的函式。
如果同名函式僅僅是返回值型別不同,有時可以區分,有時卻不能。例如:
void function(void);
int function (void);
上述兩個函式,第乙個沒有返回值,第二個的返回值是int型別。如果這樣呼叫函式:
int x = function ();
則可以判斷出function是第二個函式。問題是在c++/c程式中,我們可以忽略函式的返回值。在這種情況下,編譯器和程式設計師都不知道哪個function函式被呼叫。
所以只能靠引數而不能靠返回值型別的不同來區分過載函式。編譯器根據引數為每個過載函式產生不同的內部識別符號。例如編譯器為示例8-1-1中的三個eat函式產生象_eat_beef、_eat_fish、_eat_chicken之類的內部識別符號(不同的編譯器可能產生不同風格的內部識別符號)。
如果c++程式要呼叫已經被編譯後的c函式,該怎麼辦?
假設某個c函式的宣告如下:
void foo(int x, int y);
該函式被c編譯器編譯後在庫中的名字為_foo,而c++編譯器則會產生像_foo_int_int之類的名字用來支援函式過載和型別安全連線。由於編譯後的名字不同,c++程式不能直接呼叫c函式。c++提供了乙個c連線交換指定符號extern「c」來解決這個問題。例如:
extern 「c」
或者寫成
extern 「c」
這就告訴c++編譯器,函式foo是個c連線,應該到庫中找名字_foo而不是找_foo_int_int。c++編譯器開發商已經對c標準庫的標頭檔案作了extern「c」處理,所以我們可以用#include 直接引用這些標頭檔案。
注意並不是兩個函式的名字相同就能構成過載。全域性函式和類的成員函式同名不算過載,因為函式的作用域不同。例如:
void print(…); // 全域性函式
class a
不論兩個print函式的引數是否不同,如果類的某個成員函式要呼叫全域性函式print,為了與成員函式print區別,全域性函式被呼叫時應加『::』標誌。如
::print(…); // 表示print是全域性函式而非成員函式
當心隱式型別轉換導致過載函式產生二義性
示例8-1-3中,第乙個output函式的引數是int型別,第二個output函式的引數是float型別。由於數字本身沒有型別,將數字當作引數時將自動進行型別轉換(稱為隱式型別轉換)。語句output(0.5)將產生編譯錯誤,因為編譯器不知道該將0.5轉換成int還是float型別的引數。隱式型別轉換在很多地方可以簡化程式的書寫,但是也可能留下隱患。
# include
void output( int x); // 函式宣告
void output( float x); // 函式宣告
void output( int x)
void output( float x)
void main(void)
示例8-1-3 隱式型別轉換導致過載函式產生二義性
8 1 函式過載的概念
8.1.1 過載的起源 自然語言中,乙個詞可以有許多不同的含義,即該詞被過載了。人們可以通過上下文來判斷該詞到底是哪種含義。詞的過載 可以使語言更加簡練。例如 吃飯 的含 義十分廣泛,人們沒有必要每次非得說清楚具體吃什麼不可。別迂腐得象孔已己,說茴香豆的茴字有四種寫法。在 c 程式中,可以將語義 功...
mysql 函式過載 C 方法過載(函式過載)
在講解 c 構造方法 時提到定義構造方法時提到可以定義帶 0 到多個引數的構造方法,但構造方法的名稱必須是類名。實際上,這就是乙個典型的方法過載,即方法名稱相同 引數列表不同。引數列表不同主要體現在引數個數或引數的資料型別不同。在呼叫過載的方法時系統是根據所傳 遞引數的不同判斷呼叫的是哪個方法。例項...
c 函式的過載
函式過載的實質 用同樣的名字再定義一次乙個有著不同引數但有著同樣用途的函式。可以是引數個數不同,也可以是引數型別不同。過載不是物件導向特徵 函式的過載 對函式 方法 進行過載要謹慎 過載函式越多,該程式就越不容易看懂 注意區分過載和覆蓋 我們只能通過不同的引數過載,不能通過不同的返回值 對函式過載的...