C 函式過載

2021-08-25 19:26:42 字數 3613 閱讀 9222

一、函式過載:

過載函式是函式的一種特殊情況,為方便使用,c++允許在同一範圍中宣告幾個功能類似的同名函式,但是這些同名函式的形式引數(指引數的個數、型別或者順序)必須不同,也就是說用同乙個運算子完成不同的運算功能。這就是過載函式。過載函式常用來實現功能類似而所處理的資料型別不同的問題。但是過載函式的返回值型別可以不同。

兩個過載函式必須在下列乙個或兩個方面有所區別:

1、函式的引數個數不同。

2、函式的引數型別不同或者引數型別順序不同,

c++的這種程式設計機制給程式設計者極大的方便,不需要為功能相似、引數不同的函式選用不同的函式名,也增強了程式的可讀性。

(1)不能改變運算子的優先順序;

(2)不能改變運算子的結合型;

(3)預設引數不能和過載的運算子一起使用;

(4)不能改變運算子的運算元的個數;

(5)不能建立新的運算子,只有已有運算子可以被過載;

(6)運算子作用於c++內部提供的資料型別時,原來含義保持不變。

過載函式(overloaded function)是c++支援的一種特殊函式,c++編譯器對函式過載的判斷更是c++語言中極為複雜的內容之一。

首先我們先明確一下過載函式的定義:在相同的宣告域中的函式名相同的,而參數列不同的,即通過函式的參數列而唯一標識並且來區分函式的一種特殊的函式。

您也許要問,函式為什麼要過載呢?何時應該選擇函式過載(function overloading),何時又不呢?這也是我要在下面介紹的。

函式的過載其實就是「一物多用」的思想(這裡指的「物」是「函式名」),其實不僅是函式可以過載,運算子也是可以過載的。例如:運算子「<<」和「>>」既可以作為移位運算子,又可以作為輸出流中的插入運算子和輸入流中的提取運算子。

當將要定義一組函式,使它們執行一系列的操作,但是它們是應用在不同的引數型別上的。此時我們可以選擇過載函式。

例如: int z_x_max (int,int); //返回兩個整數的最大值;

int ve_max (const vector &); //返回vector容器中的最大值;

int matrix_max (const matrix &); //返回matrix引用的最大值;

上面的三個函式都可以大概地說成判斷一組數中的最大值,對於函式的使用者來說,他們並不關心函式定義的細節,也就是說他們不關心判斷兩個整數的大小和判斷陣列(vector容器)數的大小應該使用不同的函式,而對於程式的設計者來說這可是不得不想到的。程式設計師必須記住並查詢每個函式名。而函式的過載把程式設計師從這種問題的複雜性中解放了出來,c++提供了這種支援。上面的三個比較大小的函式可以定義成:

int max (int,int); //返回兩個整數的最大值;

int max (const vector &); //返回vector容器中的最大值;

int max (const matrix &); //返回matrix引用的最大值;

通過引數就可以一眼分辨不同的函式。

同時函式的過載也有它不適用的情況。例如:在開發文字編輯器的過程中,會涉及到一系列控制游標的函式,如下:

screen& moveup( );

screen& movedown( );

screen& moveleft( );

screen& moveright( );

看過這四個函式不言而喻,它們是控制游標在螢幕上的位置的,即:向上移動游標,向下移動游標,向左移動游標,向右移動游標。如果我現在把它們寫成過載函式,每個都是screen& move( );顯然對於程式設計師來說是不易理解的。因此對於函式過載的使用我們應遵循應用的邏輯,而不是簡單地因為它的存在就必須使用它。程式設計師不應該勉強使用過載函式。

您有沒有想過c++編譯器是如何判斷您呼叫的是過載中的哪個函式?即使它們的函式名相同。您也許會毫不猶豫的回答:是通過函式的參數列。其實識別的過程並不是像您想象中的那麼的容易,其中涉及到引數的等級劃分,引數轉換等諸多方面,下面我就一一進行講解。

假如有下面一組函式:

voids();

voids(int);

voids(doubledouble=1.2);

voids(constchar*,constchar*);

voidmax(intint);

//……

intmain()

//s(2.4);的呼叫與s();s(int);s(double,double=1.2);s(constchar*,constchar*),的宣告在同一域,即是可見的。

那麼好,問題出現了。s (2.4 );將呼叫上面四個函式中的哪乙個呢?

編譯器判斷過載函式的第一步是確定該呼叫中所考慮的過載函式的集合,該函式集合被稱為候選函式(candidant function)。所謂候選函式就是與被呼叫函式同名的函式。上面的前四個函式都可以成為候選函式(當然可以是多個),而唯有max ( int , int ) 被排除在外了。

編譯器判斷過載函式的第二步分為兩動作。第乙個動作是編譯器從第一步選出的候選函式中調出可行函式(viable function)。可行函式的函式引數個數與呼叫的函式引數個數相同(如s ( int )),或者可行函式的引數可以多一些,但是多出來的函式引數都要有相關的預設值(如 s (double , double =1.2 );)第二個動作是根據引數型別的轉換規則將被呼叫的函式實參轉換(conversion)成候選函式的實參。這裡本著充分利用引數型別轉換的原則,換句話說,盡可能的使用上引數型別轉換。當然轉換要以候選函式為轉換的目標。上面的函式中只有兩個是可行函式,它們分別是s ( int ); s ( double , double )。

如果依照引數轉換規則沒有找到可行函式,則該呼叫就是錯誤的,則說沒有函式與呼叫匹配,屬於無匹配情況(no match function)。

編譯器判斷過載函式的第三步是從第二步中選出的可行函式中選出最佳可行函式(best match situation)。在最佳可行函式的選擇中,從函式實參型別到相應可行函式引數所用的轉化都要劃分等級,根據等級的劃分(ranked),最後選出最佳可行函式。

例子,交換兩個數:

#include #include using namespace std;

/* 注意傳遞引用或者指標 */

void swap_two(int &a, int &b)

{ cout<<"int num"《結果:

li@li:~/c++$ ./a.out 

before  swap 

a = 3,b =4

c = 5,d =9

x = 100,y =200

int num

double num

long num

after  swap 

a = 4,b =3

c = 9,d =5

x = 200,y =100

mysql 函式過載 C 方法過載(函式過載)

在講解 c 構造方法 時提到定義構造方法時提到可以定義帶 0 到多個引數的構造方法,但構造方法的名稱必須是類名。實際上,這就是乙個典型的方法過載,即方法名稱相同 引數列表不同。引數列表不同主要體現在引數個數或引數的資料型別不同。在呼叫過載的方法時系統是根據所傳 遞引數的不同判斷呼叫的是哪個方法。例項...

C 函式 函式過載

如果同一作用域內的幾個函式名字相同但形參列表不同,我們稱之為過載函式。void print const char cp void print const int beg,const int end void print const int ia,size t size 這些函式接受的形參型別不一樣,...

C 函式過載

函式過載 overloaded function 在相同的作用域中的兩個函式,如果有相同的名字而形參表不同 注意 如果僅僅函式的返回值不同是不能實現函式過載 void func int int func int error,僅僅返回值不同是不能作為函式過載,這屬於函式重定義 形參表包括 引數的型別 ...