C 函式過載

2021-08-31 07:40:05 字數 2523 閱讀 8602

函式過載:是函式的一種特殊情況,c++允許在同一 作用域中宣告幾個功能類似的同名函式,這些同名函式的形參列表(引數個數或型別或順序)必須不同,常用來處理實現功能類似資料型別不同的問題。

函式過載是指在同一作用域內,可以有一組具有相同函式名,不同引數列表的函式,這組函式被稱為過載函式。過載函式通常用來命名一組功能相似的函式,這樣做減少了函式名的數量,避免了名字空間的汙染,對於程式的可讀性有很大的好處。

int add(int left, int right)

double add(double left, double right)

int main()

上面**就構成了函式的過載,知道了函式過載的概念,下面我們就看一組**:

int add(int left, int right)

short add(int left, int right)

分析:這兩個函式不構成函式過載,因為他們兩個只有返回型別不一樣,引數列表一模一樣,而函式過載是指在同一作用域內,可以有一組具有相同函式名,不同引數列表的函式,這組函式被稱為過載函式,概念中並沒有提到返回型別。

c++為什麼支援函式過載?

1.如果沒有函式過載機制,在c語言中,我們就必須要這樣去做:比如我們定義乙個print的變數,就得為這個print函式取不同的名字,如print_int、print_string。這裡還只是兩個的情況,如果是很多個的話,就需要為實現同乙個功能的函式取很多個名字,如加入列印long型、char*、各種型別的陣列等等。這樣做很不友好!

2.類的建構函式跟類名相同,也就是說:建構函式都同名。如果沒有函式過載機制,要想例項化不同的物件,那是相當的麻煩!

3.操作符過載,本質上就是函式過載,它大大豐富了已有操作符的含義,方便使用,如 + 可用於連線字串等!

接下來說說,c++是怎樣支援函式過載的?

說起這個,首先要知道編譯器是如何編譯乙個程式的,乙個程式執行起來,需要進行:

1.預處理:展開標頭檔案/進行巨集替換/條件編譯/去注釋,之後形成test.i檔案

2.編譯:檢查語法錯誤,生成彙編(這裡的彙編是一門語言指令集語言)**,完成之後,生成test.s檔案

3.彙編(指的是編譯的過程):把彙編**生成二進位制的機器碼。生成test.o檔案,同時生成符號表

而在過載函式編譯之後,它的函式名就會變了,不再都是原來的函式名,這是就不存在命名衝突的問題了。

c語言又為什麼不支援函式過載?

c語言的名字修飾規則非常簡單,只是在函式名字前面新增了下劃線。比如,對於以下**,在最後鏈結時就會出錯:

int add(int left, int right)

int main()

如果c語言支援過載的話,因為函式名相同,宣告的時候,沒有定義,只是拿函式名類似於做標記一樣,告訴編譯器,有這個東西,只是還沒有找到,兩個函式名一樣,而且都沒有找到自己的位址,這時候就分不清數哪個是哪個了,還有就是在鏈結時,符號表裡面也是有兩個一樣的函式名,根本分不清哪個是哪個,所以說c語言不支援函式過載。

而c++支援過載,就要解決這個問題,也說明c++符號表裡面類似於標記的這個位置,並不是拿函式名來鏈結的。

兩個函式要構成過載,它的函式名是相同的,主要是引數的不同,所以只要把引數的型別引用進來,就可以區別開來,這時候就引入了函式名修飾規則。函式名修飾規則是指在符號表裡面,不能單純的拿函式名做名稱,而要對這個名稱加入一些修飾,把型別的修飾給帶上,這樣即使函式名相同,也不會出現分不清楚的問題。

name mangling(名字修飾)

是一種在編譯過程中,將函式、變數的名稱重新改編的機制,簡單來說就是編譯器為了區分各個函式,將函式通過某種演算法,重新修飾為乙個全域性唯一的名稱。

比如:

int add(int left, int right)

double add(double left, double right)

以linux下修飾規則為例:

上面**中第乙個add就會修飾為:_zadd3ii(其中,3表示函式名的位元組數,add是函式名,i指的是型別int的首字母)

第二個add就會修飾為:_z3adddd(同樣,3表示函式名的位元組數,add是函式名,d指的是型別double的首字母)

如果型別是int,double,修飾出來的就是_z3addid;如果型別是double,int,修飾出來的就是_z3adddi。所以說,只要函式引數的型別不同,修飾出來的名稱就不同,鏈結的時候,就能區分開來,符號表也能區分他們。

c++函式過載在編譯器底層是如何處理的?

編譯器實際在底層使用的不是add名字,而是被重新修飾過的乙個比較複雜的名字,被重新修飾後的名字中包含了:函式的名字以及引數型別。這就是為什麼函式過載中幾個同名函式要求其引數列表不同的原因。只要引數列表不同,編譯器在編譯時通過對函式名字進行重新修飾。將引數型別包含在最終的名字中,就可保證名字在底層的全域性唯一性。

在c++中,能否將乙個函式按照c的風格來編譯?

只要在函式前加上:「extern c」即可,意思是告訴編譯器將該函式按照c語言風格來編譯。

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,僅僅返回值不同是不能作為函式過載,這屬於函式重定義 形參表包括 引數的型別 ...