一、函數重載的概念
在實際開發中,有時候我們需要實現幾個功能類似的函數,例如把變量的值寫入文件,變量的類型可能是int、long、double、char,通過參數把變量傳入函數。在C語言中不允許函數同名,程序員只能設計出四個不同名的函數,其函數聲明如下:
bool writetofile_int(char *filename,int value); // 寫入int
bool writetofile_long(char *filename,long value); // 寫入long
bool writetofile_double(char *filename,double value); // 寫入double
bool writetofile_char(char *filename,char *value); // 寫入char字符串
C語言中函數命名不能重復對程序員是一種負擔,編程序的時候需要想象出相近的函數名,調用函數的時候,書寫函數名也是一件麻煩的事情。
C++允許多個函數擁有相同的名字,只要它們的參數列表不同就可以,這就是函數的重載(Function Overloading),借助重載,多個功能相近的一系列函數可以使用同一函數名。
函數的參數列表包括參數的類型、參數的個數和參數的順序,只要有一個不同就叫做參數列表不同。
使用C++函數重載,把變量的值寫入文件的函數聲明修改如下:
bool writetofile(char *filename,int value); // 寫入int
bool writetofile(char *filename,long value); // 寫入long
bool writetofile(char *filename,double value); // 寫入double
bool writetofile(char *filename,char *value); // 寫入char字符串
重載就是在一個作用范圍內(同一個程序、同一個類、同一個命名空間等)有多個名稱相同但參數列表不同的一系列函數。
在使用重載函數時,同名函數的功能應當相似,不要用相同名稱的函數名去實現不相干的功能,雖然程序也能運行,但可讀性不好,使人覺得莫名其妙。
注意,參數列表不同包括參數的個數不同、類型不同或順序不同,僅僅參數名稱不同是不可以的,函數返回值也不能作為重載的依據。
二、C++ 是如何做到函數重載的
編譯器在編譯C++程序時會根據參數列表對函數進行重命名,例如:
bool writetofile(char *filename,int value);
重命名為
bool _writetofile_char_int(char *filename,int value);
bool writetofile(char *filename,long value);
重命名為
bool _writetofile_char_long(char *filename,long value);
程序被編譯時,編譯器會根據參數列表逐個匹配,選擇對應的函數,如果匹配失敗,編譯器就會報錯,這叫做重載決議(Overload Resolution)。
所以,函數重載僅僅是語法層面的,本質上它們還是不同的函數,占用不同的內存,入口地址也不一樣。
三、函數重載的示例
我們在介紹C語言字符串的時候,學習了strcpy函數。
char *strcpy(char *dest, const char *src);
strcpy函數有兩個缺陷:1)沒有對dest變量進行初始化;2)如果src的長度超過dest,會造成內存溢出。
我們現在來重寫strcpy函數,彌補這兩個缺陷,新函數名還是采用strcpy命名,但參數列表不同,聲明如下:
char *strcpy(char *dest, const char *src,size_t destsize);
dest和src參數的含義與庫函數strcpy相同,第三個參數destsize是dest占用內存的大小。
示例(book201.cpp)
/*
* 程序名:book201.cpp,此程序用於演示C++函數重載,修復strcpy函數的缺陷
* 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <string.h>
// 重載strcpy函數,對dest初始化,防止內存溢出。
char *strcpy(char *dest, const char *src,size_t destsize);
int main()
{
char dest[10];
strcpy(dest,"www.freecplus.net",sizeof(dest)); // 新strcpy
printf("=%s=\n",dest);
strcpy(dest,"www.freecplus.net"); // 舊strcpy
printf("=%s=\n",dest);
}
// 重載strcpy函數,對dest初始化,防止內存溢出
char *strcpy(char *dest, const char *src,size_t destsize)
{
memset(dest,0,destsize); // 對dest初始化
// 計算需要復制的字符數,不能超出destsize-1
size_t len=0;
if (strlen(src)<=destsize-1) len=strlen(src);
else len=destsize-1;
strncpy(dest,src,len); // 復制字符串,超出的將扔掉
dest[len]=0; // 強制字符串的結尾標志
return dest;
}
運行效果
C語言提供了一些庫函數,這些庫函數的功能肯定不能滿足實際開發的需求,需要程序員重新擴展加固,這是優秀程序員與普通程序員的差別。
四、課后作業
1)編寫示例程序,把本章節介紹的知識點全部演示一遍,用程序演示可以加深您的理解和映象。
2)編寫示例程序,測試函數的返回值不同能否作為函數重載的依據。
3)編寫示例程序,測試函數的參數名不同能否作為函數重載的依據。
五、版權聲明
C語言技術網原創文章,轉載請說明文章的來源、作者和原文的鏈接。
來源:C語言技術網(www.freecplus.net)
作者:碼農有道
如果文章有錯別字,或者內容有錯誤,或其他的建議和意見,請您留言指正,非常感謝!!!