這篇文章,我將談談我自己對函數重載的簡單認識。
1開始,我們得明白,函數重載是甚么??為何要函數重載??函數重載可以做哪些
事??函數重載是指在同1作用域內,可以有1組具有相同函數名,不同參數列表的函
數,這組函數被稱為重載函數。重載函數通經常使用來命名1組功能相似的函數,這樣做減
少了函數名的數量,避免了名字空間的污染,對程序的可讀性有很大的好處。
首先我先解釋名字空間這個概念。還是實例吧。
這里std就是1個命名空間,標準輸入輸出流對象cin,cout都包括在std這個名字空間
里,而std又包括在iostream這個頭文件中。固然了。我們也能夠自定義名字空間。
看下邊的實例。
下邊進入正題。
在.c文件中,寫出下邊1段的代碼:
背后的故事》中提到程序從編譯到運行出結果的進程中的幾個階段。其中有1個階段提
到生成符號表。我們來看1下上邊的函數成的符號表。符號表是在.map文件里,在vs里默許不顯示符號表文件。要想顯示出來,這樣設置:
工程名右擊--->屬性---->鏈接器----->調試---->生成映照文件選擇是。
其實吧,上邊兩個函數在c中根本編譯不通過(報錯:Add函數已有主體)就沒法生成符
號表。所以,我們去掉1個函數,讓程序編譯通過,看看函數名在符號表中的命名。
通過這個我們可以得出,函數在符號表中的命名就是函數名前邊加個下劃線。所以如果
1個程序中出現了同名函數,他們在符號表中的命名1樣,這樣調用時就出現了沖突。
要是上邊的1段程序在cpp文件中運行,來看看情況。
這里我們可以看出,雖然兩個函數的函數名1樣,但是他們在符號表中生成的名稱不1
樣。‘?’表示名稱開始,‘?’后邊是函數名“@@YA”表示參數表開始,后邊的3個字符分別
表示返回值類型,兩個參數類型。“@Z”表示名稱結束。
由于兩個函數生成的符號表中的名稱不1樣,所以是可以編譯通過的。
思考:如果在cpp文件里調用c文件里的函數,這樣可以不???
其實,這段程序編譯通過,連接不通過,報錯是沒法解析的外部符號。由于在c文件中的
符號名是_Add,而在cpp文件中生成的其實不是(看上圖)。所以在cpp文件里調用c文件
里的函數,其實不能成功。
處理這類問題的解決辦法是:
將cpp文件里的聲明語句改成:
這就是告知編譯器聲明的函數是c提供的。下邊我們來看1下在linux虛擬機下生成的符
號表文件。cpp文件在linux虛擬機里需要用g++編譯。安裝g++很簡單。1句命令就好。
yum install gcc gcc-c++
安裝好了以后就能夠了。
運行程序以后,使用命令:objdump a.out -t > test.out
-t是表示生成符號表,最后是將生成的符號表放在test.out文件。打開test.out文件,就會
發現,整形數相加的函數生成的符號就是 _Z3Addii。_Z表示符號表名稱開始。‘3’表示函
數名的字符個數。i是int的縮寫。是的,linux下生成符號表中的符號完全不同于wiindows
下。
到這里,文章1開始的幾個問題都應當明白了。在c++里才有函數重載,c里并沒有,但
是c可使用回調函數來實現功能相近的函數。
好了,關于函數重載就到這里。有問題私我~~郵箱:1521107105@qq.com