函數(shù)重載:是函數(shù)的一種特殊情況,C++允許在同一作用域中聲明幾個功能類似的同名函數(shù),這些同名函數(shù)的 形參列表(參數(shù)個數(shù) 或 類型 或 順序)必須不同,常用來處理實現(xiàn)功能類似數(shù)據(jù)類型不同的問題。
創(chuàng)新互聯(lián)公司是一家專注網(wǎng)站建設(shè)、網(wǎng)絡(luò)營銷策劃、成都小程序開發(fā)、電子商務(wù)建設(shè)、網(wǎng)絡(luò)推廣、移動互聯(lián)開發(fā)、研究、服務(wù)為一體的技術(shù)型公司。公司成立十余年以來,已經(jīng)為千余家成都發(fā)電機維修各業(yè)的企業(yè)公司提供互聯(lián)網(wǎng)服務(wù)?,F(xiàn)在,服務(wù)的千余家客戶與我們一路同行,見證我們的成長;未來,我們一起分享成功的喜悅。int add(int a, int b, int c)
{
return a+b+c;
}
int add(int a, int b)
{
return a+b;
}
int main()
{
add(1,2,3);
add(1,2);
return 0;
}
? 思考下面一段代碼,下面兩個函數(shù)是否屬于函數(shù)重載,他們有沒有什么問題?
int func()
{
return 0;
}
int func(int a=10)
{
return a;
}
int main()
{
func();
func();
return 0;
}
根據(jù)定義,函數(shù)名相同參數(shù)不同,他們當然構(gòu)成重載函數(shù),雖然他們構(gòu)成重載函數(shù),但是在使用時會有問題,因為調(diào)用函數(shù)時存在二異性。應(yīng)該避免這種情況出現(xiàn)。
? 函數(shù)重載原理? 先大概了解編譯器編譯程序過程(Linus下),現(xiàn)在有test. c、func.c、func.h三個文件。
1.預(yù)處理階段,func.h頭文件被展開、然后進行宏替換、條件編譯、去注釋。生成func.i和test.i兩個文件。
2.編譯階段,檢查語法,生成匯編代碼。生成func.s和test.s文件。
3.匯編,匯編代碼轉(zhuǎn)化為二進制機器碼,形成符號表。生成func.o和test.o文件。
4.鏈接,文件在鏈接階段被分成幾段進行操作。先進行合并段表,把相關(guān)文件對應(yīng)的段連接到一起,然后對符號表進行合并和重定向。生成func.o和test.o鏈接生成a.out文件。
? C語言不支持函數(shù)重載,因為編譯時兩個重載函數(shù)函數(shù)名相同,在func.o符號表中存在歧義和沖突,其次鏈接時也有沖突,因為C語言中是直接使用函數(shù)名標識和查找。? ? ? ? ??? ?? ?
? 而C++的目標文件符號表中不是直接使用函數(shù)名來標識和查找函數(shù),它引入了函數(shù)名修改規(guī)則,通過參數(shù)的屬性修改函數(shù)名。前面提到C++中函數(shù)重載的概念中必須有參數(shù)個數(shù) 或 類型 或 順序的不同,通過這三種參數(shù)屬性修改了函數(shù)名,不同編譯器的修改規(guī)則不同。Linus下修飾規(guī)則為_Z+函數(shù)長度+函數(shù)名+參數(shù)類型首字母。? ? ? ?
?????? ? 通過這里我們就明白了為什么C語言不支持函數(shù)重載,因為同名函數(shù)無法區(qū)分,而C++使用函數(shù)修改規(guī)則通過參數(shù)的不同屬性改變了函數(shù)名,從而就能支持重載。
二、引用 ? ? ? ? 概念引用不是新定義一個變量,而是給已存在變量取了一個別名,編譯器不會為引用變量開辟內(nèi)存空間,它和它引用的變量共用同一塊內(nèi)存空間。類型&引用變量名(對象名)=引用實體。引用在語法層沒有開辟新空間,相當于給原變量起一個新名稱。下圖我們會發(fā)現(xiàn)a和b的地址一樣。
#includeusing namespace std;
int main()
{
int a = 10;
int& b = a;
system("pause");
return 0;
}
引用的特性? 1.引用在定義時必須初始化。
void test()
{
//int& b;//編譯會出錯
}
? 2.一個變量可以有多個引用。
void test()
{
int a=10;
int& b=a;
int& c=a;
int& d=b;
}
? 3.引用一旦引用一個實體,再不能引用其他實體。
void test()
{
int a=10;
int& b=a;
int c=15;
b=c;//這里不是b引用c,而是把c的值賦給b,要和指針的使用區(qū)分
}
引用的使用? 1.引用做參數(shù),功能與傳指針參數(shù)類似。
//傳指針
void swap(int* x,int* y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
//傳引用
void swap(int& x,int& y)
{
int tmp=x;
x=y;
y=tmp;
}
int main()
{
int a=10;
int b=20;
swap(&a,&b);
swap(a,b);
return 0;
}
2.引用做返回值?
在傳值返回的函數(shù)中,因為函數(shù)執(zhí)行完成后函數(shù)棧幀已經(jīng)被銷毀,會非法訪問返回的變量,所以返回的值需要先存儲在臨時變量中。如果返回的對象較小不大于八個字節(jié),一般是寄存器充當臨時變量,如果比較大則存放在調(diào)用函數(shù)的棧幀內(nèi)。所有的傳值返回都會生成一個拷貝,當返回的數(shù)據(jù)量很大時使用引用做返回值效率會提高。
傳值返回:
??
?
下面這段代碼存在非法訪問的問題,add函數(shù)的返回值是變量c的引用,當函數(shù)執(zhí)行完成棧幀銷毀后,訪問了c的空間,如果add函數(shù)棧幀銷毀時清理空間,那么取c值時取到的就是隨機值。
#includeusing namespace std;
int& add(int x, int y)
{
int c = x + y;
return c;
}
int main()
{
//非法訪問c的空間
int ret = add(10, 20);
return 0;
}
? 上面的例子是一個錯誤的用法,那么該如何使用引用返回?如果函數(shù)返回時,出了函數(shù)作用域,如果返回的對象還在(靜態(tài)變量、全局變量等),則可以使用引用返回,否則必須使用傳值返回。
#includeusing namespace std;
int& add(int x, int y)
{
static int c = x + y;
return c;
}
int main()
{
int ret = add(10, 20);
return 0;
}
? 總結(jié)? 引用的作用主要體現(xiàn)在傳參和傳返回值
? 1.引用傳參和引用傳返回值在有些場景下可以提高性能(大對象+深拷貝對象)
? 2.引用傳參和引用傳返回值做輸出型參數(shù)和輸出型返回值。有些場景下形參的改變可以改變實參,引用返回可以改變返回對象。
? 常引用int main()
{
const int a=10;
int& b=a;//權(quán)限的放大,編譯會出錯,a只讀而b可寫
const int& b=a;//權(quán)限不變,可編譯通過
int c=10;
const int& d=c;//權(quán)限的縮小,編譯可以通過
return 0;
}
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
當前名稱:C語言到C++(基礎(chǔ)語法二)-創(chuàng)新互聯(lián)
文章轉(zhuǎn)載:http://www.rwnh.cn/article0/dgspoo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計公司、面包屑導航、微信小程序、響應(yīng)式網(wǎng)站、做網(wǎng)站、企業(yè)網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容