【連載】重溫C++之“重載”(第三篇)
1、簡單聊一聊
今天為大家推薦一首陳同學(xué)版本的《離人》,這首歌曲也是很早之前朋友向我推薦的,目前也是在作者的音樂收藏夾中,經(jīng)常隨機(jī)播放到,大家有時間可以聽一下!
今天為大家?guī)碇販?a href="/tags/C++" target="_blank">C++的第三篇文章,作者本次計劃連載大概5篇文章吧,雖然目前還有一些小伙伴沒有閱讀該連載文章,不過后續(xù)作者講解到C++方面一些有趣應(yīng)用的時候可以回頭看看這次連載文章,對于正在學(xué)習(xí)C++的小伙伴就需要更加好好練習(xí)了。好了,下面進(jìn)入今天的正題!
2、函數(shù)帶默認(rèn)參數(shù)
函數(shù)帶默認(rèn)值算是C++里面一個比較容易理解的知識,C語言中函數(shù)沒有這種使用方法,這里主要是為了后面的函數(shù)重載進(jìn)行鋪墊,所以這里作者簡單溫習(xí)一下用法和注意事項,函數(shù)帶默認(rèn)參數(shù)主要是說函數(shù)在定義或者聲明的時候可以為函數(shù)形參指定默認(rèn)的參數(shù),后續(xù)使用可以不用傳入相對應(yīng)的參數(shù)使用缺省值即可,參考如下代碼:
1#include <iostream>
2using namespace std;
3/******************************************
4 * Fuction: Printf1
5 * Author : (公眾號:最后一個bug)
6 *****************************************/
7int Printf1(int a = 1 ,int b = 2)
8{
9 cout<<"Printf1 : a = "<<a<<";b = "<<b<<endl;
10}
11
12int Printf2(int a = 1 ,int b = 2);
13int Printf3(int a ,int b = 2);
14/******************************************
15 * Fuction: 測試函數(shù)默認(rèn)值
16 * Author : (公眾號:最后一個bug)
17 *****************************************/
18int main(int argc, char** argv) {
19
20 cout<<"Test:函數(shù)默認(rèn)值 "<<endl;
21 cout<<"----------------- "<<endl;
22 //Printf1
23 Printf1();
24 Printf1(4);
25 Printf1(4,5);
26 //Printf2
27 cout<<"----------------- "<<endl;
28 Printf2();
29 Printf2(4);
30 Printf2(4,5);
31 //Printf3
32 cout<<"----------------- "<<endl;
33 //Printf3(); 需要傳遞第一個參數(shù)
34 Printf3(4);
35 Printf3(4,5);
36 cout<<"--公眾號:最后一個bug--"<<endl;
37 return 0;
38}
39
40/******************************************
41 * Fuction: Printf2
42 * Author : (公眾號:最后一個bug)
43 *****************************************/
44int Printf2(int a,int b)
45{
46 cout<<"Printf2 : a = "<<a<<";b = "<<b<<endl;
47}
48/******************************************
49 * Fuction: Printf3
50 * Author : (公眾號:最后一個bug)
51 *****************************************/
52int Printf3(int a,int b)
53{
54 cout<<"Printf3 : a = "<<a<<";b = "<<b<<endl;
55}
其輸出結(jié)果如下:
解析一下:作者定義了三種函數(shù)帶默認(rèn)參數(shù)的形式,Printf1是直接在定義確定參數(shù)缺省值;Printf2是在函數(shù)聲明處提供缺省值;Printf3只提供部分參數(shù)缺省值,具體使用情況參考上面的代碼。
注意事項:
1)函數(shù)參數(shù)自左向右從第一提供缺省值的參數(shù)開始往右的參數(shù)都需要提供缺省參數(shù);
2)雖然缺省參數(shù)能夠放在定義或者聲明,盡量放在聲明,如果放在定義處,定義之前均無法提供缺省參數(shù),會存在編譯不通過的情況。
3)由于提供了缺省值,對于程序的編碼也會變得更加簡潔,不過注意其實際調(diào)用函數(shù)所傳入的實參都是從左向右,且不會跳躍。
3、函數(shù)重載
重載簡單一點說就是同一句話在不同的語境中表達(dá)著不同的意思,比如說在C語言中一般都不允許有同名的全局函數(shù)出現(xiàn),而在C++中可以根據(jù)函數(shù)的參數(shù)不同而存在相同名字的函數(shù),這就是函數(shù)重載。下面作者簡單的寫個小代碼,供大家參考:
1#include <iostream>
2using namespace std;
3
4int Fuction(int a,int b);
5int Fuction(int a,int b,int c);
6float Fuction(float a,float b);
7/******************************************
8 * Fuction: 測試函數(shù)重載
9 * Author : (公眾號:最后一個bug)
10 *****************************************/
11int main(int argc, char** argv) {
12
13 cout<<"Test:函數(shù)重載"<<endl;
14 cout<<"result1: "<<Fuction(1,1)<<endl;
15 cout<<"result2: "<<Fuction(1,1,1)<<endl;
16 cout<<"result3: "<<Fuction((float)2.0,(float)5.0)<<endl;
17 cout<<"--公眾號:最后一個bug--"<<endl;
18 return 0;
19}
20int Fuction(int a,int b)
21{
22 return (a + b);
23}
24int Fuction(int a,int b,int c)
25{
26 return (a + b + c);
27}
28float Fuction(float a,float b)
29{
30 return (a * b);
31}
輸出結(jié)果如下:
解析一下:通過上面的程序我們大體可以知道,我們通過函數(shù)參數(shù)的差異調(diào)用相同的函數(shù)名會最終調(diào)用不同的函數(shù)實現(xiàn)。這種方式就非常符合我們現(xiàn)實的生活,比如用錄音機(jī)播放音樂,通過放置不同的磁帶就可以播放不同的音樂了,所以說C++語言的特性更加符合人類的思維。
注意事項:
1)函數(shù)重載時函數(shù)名稱必須相同,其形參存在差異,比如:參數(shù)的類型,參數(shù)的個數(shù),參數(shù)的順序。
2)單獨(dú)的函數(shù)返回值不同不能作為重載的依據(jù)。
3)其實函數(shù)重載僅僅只是名稱相同,他們本質(zhì)屬于不同的函數(shù),在編譯階段編譯器能夠通過函數(shù)的參數(shù)不同來進(jìn)行編譯處理,同時也增加代碼了代碼的可讀性,如果無法通過名字的參數(shù)進(jìn)行區(qū)分或者存在二義性,那么會導(dǎo)致編譯錯誤 : 比如我們前面函數(shù)默認(rèn)值的處理,如果一個函數(shù)的參數(shù)與另外一個函數(shù)的前面參數(shù)完全一直,而另一個函數(shù)其余參數(shù)都含有默認(rèn)值,這樣就存在二義性,編譯無法通過。
4、運(yùn)算符重載
重載一般分為函數(shù)重載和運(yùn)算符重載,在我們C語言中,對于結(jié)構(gòu)體這樣的打包變量是不支持運(yùn)算符直接進(jìn)行運(yùn)算的,一般對于結(jié)構(gòu)體的運(yùn)算我們大多采用函數(shù)的形式進(jìn)行處理,然后返回最后的結(jié)構(gòu)體。
如果我們用更加統(tǒng)一的眼光看待的C的話,認(rèn)為它僅僅只能支持基本數(shù)據(jù)類型的運(yùn)算符重載。而C++語言可以重新定義這種的運(yùn)算符(如“+”等)來滿足我們的需求,下面作者給一個簡單的小程序供大家參考:
1#include <iostream>
2using namespace std;
3
4class Test
5{
6private:
7 int a;
8 int b;
9
10public:
11 Test(int param1,int param2);
12 void Printf(void);
13 friend Test operator+(Test A,Test B); //必須定義為友元
14};
15/************************************
16 * Fuction :析構(gòu)函數(shù)
17 * Author :(公眾號:最后一個bug)
18 ************************************/
19Test::Test(int param1,int param2)
20{
21 a = param1;
22 b = param2;
23}
24/************************************
25 * Fuction :Printf
26 * Author :(公眾號:最后一個bug)
27 ************************************/
28void Test::Printf(void)
29{
30 cout<<"a = "<<a<<",b = "<<b<<endl;
31
32}
33/************************************
34 * Fuction :重載加法運(yùn)算符
35 * Author :(公眾號:最后一個bug)
36 ************************************/
37Test operator+(Test A,Test B)
38{
39 Test Ret(0,0);
40
41 Ret.a = A.a + B.a;
42 Ret.b = A.b + B.b;
43
44 return Ret;
45}
46
47int main(int argc, char** argv) {
48 Test stTest1(1,2);
49 Test stTest2(1,2);
50 Test stTest3(0,0);
51
52 stTest3 = stTest1 + stTest2; //直接可以進(jìn)行加法運(yùn)算
53 stTest3.Printf();
54 cout<<"公眾號:最后一個bug"<<endl;
55 return 0;
56}
最后的輸出結(jié)果我就不貼圖了a = 2,b = 4;
解析一下 :
1)其實運(yùn)算符重載你可以簡單的認(rèn)為就是把運(yùn)算符操作用operator關(guān)鍵字定義的對應(yīng)函數(shù)來進(jìn)行調(diào)用處理即可。其實和我們平時在C語言定義函數(shù)來進(jìn)行結(jié)構(gòu)體加法運(yùn)算是一樣的道理。
2)在13行我們使用了friend關(guān)鍵字來進(jìn)行修飾,為了讓operator定義的函數(shù)內(nèi)部能夠訪問Test類的內(nèi)部私有成員,強(qiáng)調(diào)一點的是operator定義的函數(shù)不屬于類Test,如果operator函數(shù)內(nèi)部訪問其Test的私有成員屬于外部訪問,這樣是不允許的,所以我們使用了friend來為其開放訪問權(quán)限;如果我們不想直接訪問類Test內(nèi)的私有成員,我們可以在public里面為其開放對應(yīng)接口,然后在operator函數(shù)中進(jìn)行調(diào)用即可。
3)談到第二點可能很多小伙伴會問為什么不把重載函數(shù)放到類里面來實現(xiàn),這樣不就可以訪問其類的私有變量了嗎?就可以省略friend關(guān)鍵字了!確實,大家可以編碼進(jìn)行實現(xiàn),這樣有一點我們得修改類,如果采用我們現(xiàn)在的全局方式通過調(diào)用類的public接口會更加靈活一點。
4)這樣看來我們?nèi)绻€有其他的類要實現(xiàn)+法運(yùn)算,同樣需要用operator來進(jìn)行定義,同一個+法運(yùn)算就有多種用法了,所以叫運(yùn)算符重載!
5、最后小結(jié)
對于運(yùn)算符的重載,作者僅僅舉例了+法運(yùn)算,還有"=,++,&&"等等,哪些運(yùn)算符可以重載,怎么重載,還有一些注意事項,可能需要大家查找相關(guān)書籍或者文檔進(jìn)行學(xué)習(xí),基本上大同小異,都是一些語法問題,大家依葫蘆畫瓢+死記硬背基本上可以搞定,其實在真正開發(fā)的過程中,一些冷門的語法是用得很少的,甚至基本上不會用,而我們學(xué)習(xí)主要是為了對這些語法不要太陌生,以后閱讀某某大佬或者項目的代碼遇到了可以回憶得起來,然后好好查查資料,印象就特別深刻了!
最近文章推薦:
點【在看】是最大的支持
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!