久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C++:引用的簡單理解

 袁先森lemon 2021-07-21

前言:引用是C++一個很重要的特性,,最近看了很多有關(guān)引用的資料和博客,故在此對引用的相關(guān)知識進行總結(jié)

一,、什么是引用

引用,,顧名思義是某一個變量或?qū)ο蟮?span style="font-size: 16px">別名,對引用的操作與對其所綁定的變量或?qū)ο蟮牟僮魍耆葍r

語法:類型 &引用名=目標變量名,;

特別注意:

1.&不是求地址運算符,,而是起標志作用

2.引用的類型必須和其所綁定的變量的類型相同

復(fù)制代碼
1 #include<iostream>
2 using namespace std;
3 int main(){
4     double a=10.3;
5     int &b=a; //錯誤,引用的類型必須和其所綁定的變量的類型相同
6     cout<<b<<endl;
7 }
復(fù)制代碼

3.聲明引用的同時必須對其初始化,,否則系統(tǒng)會報錯

復(fù)制代碼
1 #include<iostream>
2 using namespace std;
3 int main(){
4     int &a; //錯誤,!聲明引用的同時必須對其初始化
5     return 0;
6 }
復(fù)制代碼

4.引用相當于變量或?qū)ο蟮膭e名,,因此不能再將已有的引用名作為其他變量或?qū)ο蟮拿只騽e名

5.引用不是定義一個新的變量或?qū)ο螅虼?strong>內(nèi)存不會為引用開辟新的空間存儲這個引用

復(fù)制代碼
1 #include<iostream>
2 using namespace std;
3 int main(){
4     int value=10;
5     int &new_value=value;
6     cout<<"value在內(nèi)存中的地址為:"<<&value<<endl;
7     cout<<"new_value在內(nèi)存中的地址為:"<<&new_value<<endl;
8     return 0;
9 }
復(fù)制代碼

6.對數(shù)組的引用

語法:類型 (&引用名)[數(shù)組中元素數(shù)量]=數(shù)組名,;
復(fù)制代碼
 1 #include<iostream>
 2 using namespace std;
 3 int main(){
 4     int a[3]={1,2,3};
 5     int (&b)[3]=a;//對數(shù)組的引用 
 6     cout<<&a[0]<<" "<<&b[0]<<endl;
 7     cout<<&a[1]<<" "<<&b[1]<<endl;
 8     cout<<&a[2]<<" "<<&b[2]<<endl;
 9     return 0;
10 }
復(fù)制代碼

7.對指針的引用

語法:類型 *&引用名=指針名;//可以理解為:(類型*) &引用名=指針名,,即將指針的類型當成類型*
復(fù)制代碼
1 #include<iostream>
2 using namespace std;
3 int main(){
4     int a=10;
5     int *ptr=&a;
6     int *&new_ptr=ptr;
7     cout<<&ptr<<" "<<&new_ptr<<endl;
8     return 0; 
9 }
復(fù)制代碼

 

二、引用的應(yīng)用

A.引用作為函數(shù)的參數(shù)

復(fù)制代碼
 1 #include<iostream>
 2 using namespace std;
 3 void swap(int &a,int &b){//引用作為函數(shù)的參數(shù)
 4     int temp=a;
 5     a=b;
 6     b=temp; 
 7 }
 8 int main(){
 9     int value1=10,value2=20;
10     cout<<"----------------------交換前----------------------------"<<endl;
11     cout<<"value1的值為:"<<value1<<endl; 
12     cout<<"value2的值為:"<<value2<<endl;
13     swap(value1,value2); 
14     cout<<"----------------------交換后----------------------------"<<endl;
15     cout<<"value1的值為:"<<value1<<endl; 
16     cout<<"value2的值為:"<<value2<<endl;
17     return 0;
18 }
復(fù)制代碼

特別注意:

1.當用引用作為函數(shù)的參數(shù)時,,其效果和用指針作為函數(shù)參數(shù)的效果相當,。當調(diào)用函數(shù)時,函數(shù)中的形參就會被當成實參變量或?qū)ο蟮囊粋€別名來使用,,也就是說此時函數(shù)中對形參的各種操作實際上是對實參本身進行操作,,而非簡單的將實參變量或?qū)ο蟮闹悼截惤o形參

2.通常函數(shù)調(diào)用時,,系統(tǒng)采用值傳遞的方式將實參變量的值傳遞給函數(shù)的形參變量,。此時,系統(tǒng)會在內(nèi)存中開辟空間用來存儲形參變量,,并將實參變量的值拷貝給形參變量,,也就是說形參變量只是實參變量的副本而已;并且如果函數(shù)傳遞的是類的對象,,系統(tǒng)還會調(diào)用類中的拷貝構(gòu)造函數(shù)來構(gòu)造形參對象,。而使用引用作為函數(shù)的形參時,由于此時形參只是要傳遞給函數(shù)的實參變量或?qū)ο蟮膭e名而非副本,,故系統(tǒng)不會耗費時間來在內(nèi)存中開辟空間來存儲形參,。因此如果參數(shù)傳遞的數(shù)據(jù)較大時,建議使用引用作為函數(shù)的形參,,這樣會提高函數(shù)的時間效率,,并節(jié)省內(nèi)存空間

3.使用指針作為函數(shù)的形參雖然達到的效果和使用引用一樣,,但當調(diào)用函數(shù)時仍需要為形參指針變量在內(nèi)存中分配空間,,而引用則不需要這樣,故在C++中推薦使用引用而非指針作為函數(shù)的參數(shù)

4.如果在編程過程中既希望通過讓引用作為函數(shù)的參數(shù)來提高函數(shù)的編程效率,,又希望保護傳遞的參數(shù)使其在函數(shù)中不被改變,,則此時應(yīng)當使用對常量的引用作為函數(shù)的參數(shù)。

5.數(shù)組的引用作為函數(shù)的參數(shù):C++的數(shù)組類型是帶有長度信息的,,引用傳遞時如果指明的是數(shù)組則必須指定數(shù)組的長度

復(fù)制代碼
 1 #include<iostream>
 2 using namespace std;
 3 void func(int(&a)[5]){//數(shù)組引用作為函數(shù)的參數(shù),,必須指明數(shù)組的長度 
 4 //函數(shù)體 
 5 }
 6 int main(){
 7     int number[5]={0,1,2,3,4};
 8     func(number); 
 9     return 0; 
10  }
復(fù)制代碼

 B.常引用

語法:const 類型 &引用名=目標變量名;

常引用不允許通過該引用對其所綁定的變量或?qū)ο筮M行修改

復(fù)制代碼
1 #include<iostream>
2 using namespace std;
3 int main(){
4     int a=10;
5     const int &new_a=a;
6     new_a=11;//錯誤,!不允許通過常引用對其所綁定的變量或?qū)ο筮M行修改 
7     return 0;
8 }
復(fù)制代碼

特別注意:

先看下面的例子

復(fù)制代碼
 1 #include<iostream>
 2 #include<string> 
 3 using namespace std;
 4 string func1(){
 5     string temp="This is func1";
 6     return temp;
 7 }
 8 void func2(string &str){
 9     cout<<str<<endl;
10 }
11 int main(){
12     func2(func1());
13     func2("Tomwenxing");
14     return 0;
15 }
復(fù)制代碼

運行上面的程序編譯器會報錯

這是由于func1()和“Tomwenxing”都會在系統(tǒng)中產(chǎn)生一個臨時對象(string對象)來存儲它們,,而在C++中所有的臨時對象都是const類型的,而上面的程序試圖將const對象賦值給非const對象,這必然會使程序報錯,。如果在函數(shù)func2的參數(shù)前添加const,則程序便可正常運行了

復(fù)制代碼
 1 #include<iostream>
 2 #include<string> 
 3 using namespace std;
 4 string func1(){
 5     string temp="This is func1";
 6     return temp;
 7 }
 8 void func2(const string &str){
 9     cout<<str<<endl;
10 }
11 int main(){
12     func2(func1());
13     func2("Tomwenxing");
14     return 0;
15 }
復(fù)制代碼

C.引用作為函數(shù)的返回值

語法:類型 &函數(shù)名(形參列表){ 函數(shù)體 }

特別注意:

1.引用作為函數(shù)的返回值時,,必須在定義函數(shù)時在函數(shù)名前將&

2.用引用作函數(shù)的返回值的最大的好處是在內(nèi)存中不產(chǎn)生返回值的副本

復(fù)制代碼
 1 //代碼來源:RUNOOB
 2 #include<iostream>
 3 using namespace std;
 4 float temp;
 5 float fn1(float r){
 6     temp=r*r*3.14;
 7     return temp;
 8 } 
 9 float &fn2(float r){ //&說明返回的是temp的引用,,換句話說就是返回temp本身
10     temp=r*r*3.14;
11     return temp;
12 }
13 int main(){
14     float a=fn1(5.0); //case 1:返回值
15     //float &b=fn1(5.0); //case 2:用函數(shù)的返回值作為引用的初始化值 [Error] invalid initialization of non-const reference of type 'float&' from an rvalue of type 'float'
//(有些編譯器可以成功編譯該語句,但會給出一個warning)
16 float c=fn2(5.0);//case 3:返回引用 17 float &d=fn2(5.0);//case 4:用函數(shù)返回的引用作為新引用的初始化值
18 cout<<a<<endl;//78.5 19 //cout<<b<<endl;//78.5 20 cout<<c<<endl;//78.5 21 cout<<d<<endl;//78.5 22 return 0; 23 }
復(fù)制代碼

 上例中4個case的說明解釋:

case 1:用返回值方式調(diào)用函數(shù)(如下圖,,圖片來源:伯樂在線):

返回全局變量temp的值時,,C++會在內(nèi)存中創(chuàng)建臨時變量并將temp的值拷貝給該臨時變量。當返回到主函數(shù)main后,,賦值語句a=fn1(5.0)會把臨時變量的值再拷貝給變量a

case 2:用函數(shù)的返回值初始化引用的方式調(diào)用函數(shù)(如下圖,,圖片來源:伯樂在線)

這種情況下,函數(shù)fn1()是以值方式返回到,,返回時,,首先拷貝temp的值給臨時變量。返回到主函數(shù)后,,用臨時變量來初始化引用變量b,,使得b成為該臨時變量到的別名。由于臨時變量的作用域短暫(在C++標準中,,臨時變量或?qū)ο蟮纳芷谠谝粋€完整的語句表達式結(jié)束后便宣告結(jié)束,,也就是在語句float &b=fn1(5.0);之后) ,所以b面臨無效的危險,,很有可能以后的值是個無法確定的值,。

 如果真的希望用函數(shù)的返回值來初始化一個引用,應(yīng)當先創(chuàng)建一個變量,,將函數(shù)的返回值賦給這個變量,,然后再用該變量來初始化引用:

1 int x=fn1(5.0);
2 int &b=x;

 case 3:用返回引用的方式調(diào)用函數(shù)(如下圖,圖片來源:伯樂在線)

這種情況下,,函數(shù)fn2()的返回值不產(chǎn)生副本,,而是直接將變量temp返回給主函數(shù),即主函數(shù)的賦值語句中的左值是直接從變量temp中拷貝而來(也就是說c只是變量temp的一個拷貝而非別名) ,,這樣就避免了臨時變量的產(chǎn)生,。尤其當變量temp是一個用戶自定義的類的對象時,這樣還避免了調(diào)用類中的拷貝構(gòu)造函數(shù)在內(nèi)存中創(chuàng)建臨時對象的過程,,提高了程序的時間和空間的使用效率,。

case 4:用函數(shù)返回的引用作為新引用的初始化值的方式來調(diào)用函數(shù)(如下圖,圖片來源:伯樂在線)

這種情況下,,函數(shù)fn2()的返回值不產(chǎn)生副本,,而是直接將變量temp返回給主函數(shù)。在主函數(shù)中,一個引用聲明d用該返回值初始化,,也就是說此時d成為變量temp的別名,。由于temp是全局變量,所以在d的有效期內(nèi)temp始終保持有效,,故這種做法是安全的,。

3.不能返回局部變量的引用。如上面的例子,,如果temp是局部變量,,那么它會在函數(shù)返回后被銷毀,此時對temp的引用就會成為“無所指”的引用,,程序會進入未知狀態(tài),。

4.不能返回函數(shù)內(nèi)部通過new分配的內(nèi)存的引用。雖然不存在局部變量的被動銷毀問題,,但如果被返回的函數(shù)的引用只是作為一個臨時變量出現(xiàn),,而沒有將其賦值給一個實際的變量,那么就可能造成這個引用所指向的空間(有new分配)無法釋放的情況(由于沒有具體的變量名,,故無法用delete手動釋放該內(nèi)存),,從而造成內(nèi)存泄漏。因此應(yīng)當避免這種情況的發(fā)生

5當返回類成員的引用時,,最好是const引用,。這樣可以避免在無意的情況下破壞該類的成員。

6.可以用函數(shù)返回的引用作為賦值表達式中的左值

復(fù)制代碼
 1 #include<iostream>
 2 using namespace std;
 3 int value[10];
 4 int error=-1;
 5 int &func(int n){
 6     if(n>=0&&n<=9)
 7         return value[n];//返回的引用所綁定的變量一定是全局變量,,不能是函數(shù)中定義的局部變量 
 8     else
 9         return error;
10 }
11 
12 int main(){
13     func(0)=10;
14     func(4)=12;
15     cout<<value[0]<<endl;
16     cout<<value[4]<<endl;
17     return 0; 
18 }
復(fù)制代碼

D.用引用實現(xiàn)多態(tài)

在C++中,,引用是除了指針外另一個可以產(chǎn)生多態(tài)效果的手段。也就是說一個基類的引用可以用來綁定其派生類的實例

class Father;//基類(父類)
class Son:public Father{.....}//Son是Father的派生類
Son son;//son是類Son的一個實例
Father &ptr=son;//用派生類的對象初始化基類對象的使用

特別注意:

ptr只能用來訪問派生類對象中從基類繼承下來的成員,。如果基類(類Father)中定義的有虛函數(shù),,那么就可以通過在派生類(類Son)中重寫這個虛函數(shù)來實現(xiàn)類的多態(tài)。

 

三,、總結(jié)

1.在引用的使用中,,單純給某個變量去別名是毫無意義的,引用的目的主要用于在函數(shù)參數(shù)的傳遞中,,解決大塊數(shù)據(jù)或?qū)ο蟮膫鬟f效率和空間不如意的問題

2.用引用傳遞函數(shù)的參數(shù),,能保證參數(shù)在傳遞的過程中不產(chǎn)生副本,從而提高傳遞效率,,同時通過const的使用,,還可以保證參數(shù)在傳遞過程中的安全性

3.引用本身是目標變量或?qū)ο蟮膭e名,對引用的操作本質(zhì)上就是對目標變量或?qū)ο蟮牟僮?。因?strong>能使用引用時盡量使用引用而非指針

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多