帶你從編碼角度分析C++重載原理

什麼是函數重載

函數重載的即是在相同作用域中的多個函數,它們具有相同的名字而型參不同,但是在C++中他們可以正常編譯,不會因為同名而出現error。這是因為在C++利用瞭name mangling(傾紮)技術,在對程序編譯之前,編譯器將會用參數個數和參數類型對每一個函數標識符進行專門編碼。

接下來我們將會使用C++和C中分別實現代碼,使用nm命令來查看可執行文件的中編譯後的函數名是怎樣的?

代碼分析

我們借用如下代碼分別使用c和c++的編譯器編譯運行,來進行分析。

int Add(int a, int b){
    return a+b;
}
float Add(float a, float b){
    return a+b;
}
int main(){
    int c = Add(10, 5);
}

C語言分析:

我們將上述代碼放入overload.c的文件中,使用c的編譯器進行分析,將會出現報錯如下:

在這裡插入圖片描述

這就是因為在我們的程序中有兩個同名的函數,也證明瞭C語言無法實現重載。那麼我們修改這段代碼,去掉一個Add函數,具體代碼如下:

int Add(int a, int b){
    return a+b;
}
int main(){
    int c = Add(10, 5);
}

編譯通過,生成可執行文件a.out,我們使用nm 可執行文件名查詢該可執行文件中編譯過的函數名如下:

在這裡插入圖片描述

我們會發現在C的編譯器下,編譯過的函數名和我們程序中自定義的函數名是相同的。接下來我們使用C++的編譯器來進行編譯。

C++分析

將不做修改的代碼放入一個overload.cpp文件中,使用C++編譯器進行編譯,會發現這次不會報錯,這也是C++中函數重載的結果,我們直接使用nm來查看編譯過的函數名。

在這裡插入圖片描述

我們會發現函數名發生瞭改變,這就是C++的編譯器對程序中的函數中的每一個函數名進行瞭編碼,其中的_z是規定前綴,3是函數名的個數,i是參數列表類型int的首字母。這個過程我們稱作“名字改編”或“名字修飾”,類型安全的連接使得程序能夠調用合適的重載函數並保證瞭參數傳遞的一致性。

註意:main函數不會進行名字改編。

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: