1. 程式人生 > >(轉載)c++引用

(轉載)c++引用

引用,顧名思義是某一個變數或物件的別名,對引用的操作與對其所繫結的變數或物件的操作完全等價

語法:型別 &引用名=目標變數名;

特別注意:

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

2.引用的型別必須和其所繫結的變數的型別相同

#include<iostream>
using namespace std;
 int main(){
     double a=10.3;
     int &b=a; //錯誤,引用的型別必須和其所繫結的變數的型別相同
     cout<<b<<endl;
 }

3.宣告引用的同時必須對其初始化,否則系統會報錯

4、引用相當於變數或物件的別名,因此不能再將已有的引用名作為其他變數或物件的名字或別名

5.引用不是定義一個新的變數或物件,因此記憶體不會為引用開闢新的空間儲存這個引用

6.對陣列的引用

語法:型別 (&引用名)[陣列中元素數量]=陣列名;
#include<iostream>
using namespace std;
int main(){
    int a[3]={1,2,3};
    int (&b)[3]=a;//對陣列的引用 
    cout<<&a[0]<<" "<<&b[0]<<endl;
    cout
<<&a[1]<<" "<<&b[1]<<endl; cout<<&a[2]<<" "<<&b[2]<<endl; return 0; }

7.對指標的引用

語法:型別 *&引用名=指標名;//可以理解為:(型別*) &引用名=指標名,即將指標的型別當成型別*
#include<iostream>
using namespace std;
int main(){
    int a=10;
    int *ptr=&a;
    
int *&new_ptr=ptr; cout<<&ptr<<" "<<&new_ptr<<endl; return 0; }

二、引用的應用

A.引用作為函式的引數
#include<iostream>
using namespace std;
void swap(int &a,int &b){//引用作為函式的引數
    int temp=a;
    a=b;
    b=temp; 
}
int main(){
    int value1=10,value2=20;
    cout<<"----------------------交換前----------------------------"<<endl;
    cout<<"value1的值為:"<<value1<<endl; 
    cout<<"value2的值為:"<<value2<<endl;
    swap(value1,value2); 
    cout<<"----------------------交換後----------------------------"<<endl;
    cout<<"value1的值為:"<<value1<<endl; 
    cout<<"value2的值為:"<<value2<<endl;
    return 0;
}

特別注意:

1.當用引用作為函式的引數時,其效果和用指標作為函式引數的效果相當。當呼叫函式時,函式中的形參就會被當成實參變數或物件的一個別名來使用,也就是說此時函式中對形參的各種操作實際上是對實參本身進行操作,而非簡單的將實參變數或物件的值拷貝給形參

2.通常函式呼叫時,系統採用值傳遞的方式將實參變數的值傳遞給函式的形參變數。此時,系統會在記憶體中開闢空間用來儲存形參變數,並將實參變數的值拷貝給形參變數,也就是說形參變數只是實參變數的副本而已;並且如果函式傳遞的是類的物件,系統還會呼叫類中的拷貝建構函式來構造形參物件。而使用引用作為函式的形參時,由於此時形參只是要傳遞給函式的實參變數或物件的別名而非副本,故系統不會耗費時間來在記憶體中開闢空間來儲存形參。因此如果引數傳遞的資料較大時,建議使用引用作為函式的形參,這樣會提高函式的時間效率,並節省記憶體空間

3.使用指標作為函式的形參雖然達到的效果和使用引用一樣,但當呼叫函式時仍需要為形參指標變數在記憶體中分配空間,而引用則不需要這樣,故在C++中推薦使用引用而非指標作為函式的引數

4.如果在程式設計過程中既希望通過讓引用作為函式的引數來提高函式的程式設計效率,又希望保護傳遞的引數使其在函式中不被改變,則此時應當使用對常量的引用作為函式的引數。

5.陣列的引用作為函式的引數:C++的陣列型別是帶有長度資訊的,引用傳遞時如果指明的是陣列則必須指定陣列的長度

B.常引用

語法:const 型別 &引用名=目標變數名;

常引用不允許通過該引用對其所繫結的變數或物件進行修改

#include<iostream>
using namespace std;
int main(){
    int a=10;
    const int &new_a=a;
    new_a=11;//錯誤!不允許通過常引用對其所繫結的變數或物件進行修改 
    return 0;
}
C.引用作為函式的返回值
語法:型別 &函式名(形參列表){ 函式體 }

特別注意:

1.引用作為函式的返回值時,必須在定義函式時在函式名前將&

2.用引用作函式的返回值的最大的好處是在記憶體中不產生返回值的副本

3.不能返回區域性變數的引用

4.不能返回函式內部通過new分配的記憶體的引用。雖然不存在區域性變數的被動銷燬問題,但如果被返回的函式的引用只是作為一個臨時變量出現,而沒有將其賦值給一個實際的變數,那麼就可能造成這個引用所指向的空間(有new分配)無法釋放的情況(由於沒有具體的變數名,故無法用delete手動釋放該記憶體),從而造成記憶體洩漏。因此應當避免這種情況的發生

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

6.可以用函式返回的引用作為賦值表示式中的左值

D.用引用實現多型

在C++中,引用是除了指標外另一個可以產生多型效果的手段。也就是說一個基類的引用可以用來繫結其派生類的例項

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

特別注意:

ptr只能用來訪問派生類物件中從基類繼承下來的成員如果基類(類Father)中定義的有虛擬函式,那麼就可以通過在派生類(類Son)中重寫這個虛擬函式來實現類的多型。

三、總結

1.在引用的使用中,單純給某個變數去別名是毫無意義的,引用的目的主要用於在函式引數的傳遞中,解決大塊資料或物件的傳遞效率和空間不如意的問題

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

3.引用本身是目標變數或物件的別名,對引用的操作本質上就是對目標變數或物件的操作。因此能使用引用時儘量使用引用而非指標

參考:https://www.cnblogs.com/duwenxing/p/7421100.html

相較於別人寫的部落格,自己寫的真的是太low了,自己一定會更加努力的,不僅僅是技術,部落格也要寫好。能夠起到交流的作用