C++中的引用

 

引用就是某個目標變量的別名,對引用的操做與對變量的直接操做效果徹底相同。 ios

引用的聲明方法:類型標識符 &引用名=目標變量名; c++

  以下:定義引用ra,它是變量a的引用,即別名。 程序員

    

int a;

 int &ra=a;
1)  聲明一個引用,必須進行初始化。

2)引用聲明完畢後,至關於目標變量有兩個名稱即該目標原名稱和引用名,且不能再把該引用名做爲其餘變量名的別名。 數組

3)引用自己不是一種數據類型,所以引用自己不佔存儲單元,系統也不會給引用分配存儲單元。 函數

4)不能創建數組的引用。由於數組是一個由若干個元素所組成的集合,因此沒法創建一個數組的別名。 spa

 

引用的本質是: 引用在C++中的內部實現是一個常量指針。 指針

Type &name  < ==>  Type * const name  (即指針的值不能被修改) code

 

將 「引用」 作函數參數有哪些特色? 對象

 

1)傳遞引用給函數跟傳遞指針的效果是同樣的。 blog

 

2) 使用引用傳遞函數的參數,在內存中沒有產生實參的副本,它是直接對實參的操做。 而使用通常變量傳遞函數的參數,當發生函數調用時,須要給形參分配存儲單元,形參變量是實參變量的副本;若是傳遞是對象,還將調用拷貝構造函數。所以,在參數傳遞的數據較大時,用引用比用通常變量傳遞參數效率和所佔空間都好

 

3) 雖然用指針做爲函數參數也能達到一樣的效果。可是,在被調用函數中 一樣要給形參分配存儲單元,並且重複使用「*指針變量名」的形式進行操做,很容易產生錯誤且程序的閱讀性較差,另外一方面,在主調函數的調用點處,必須使用變量的地址做爲實參。而引用更容易,更清晰。

 

函數返回值是引用(引用當左值)

 

1 當函數返回值爲引用時

若返回的是棧變量,不能成爲其餘引用的初始值,不能做爲左值使用。

include <iostream>
using namespace std;

int getAA1()
{
    int a ;
    a = 10;
    return a;
}

//返回a的自己 返回a的一個副本 10 
int& getAA2()
{
    int a ; //若是返回棧上的引用, 有可能會有問題
    a = 10;
    return a;
}

int* getAA3()
{
    int a ;
    a = 10;
    return &a;
}

void main()
{
    int a1 = 0;
    int a2 = 0;
    a1 = getAA1();

    a2 = getAA2();   // a2 = 10

int &a3 = getAA2(); ////若返回棧變量 不能成爲其它引用的初始值,關鍵是看變量是否是被編譯器回收了
printf("a1:%d \n", a1);
printf("a2:%d \n", a2);
printf("a3:%d \n", a3);// 至關於*a3 去讀取值,但是此時局部變量已經被回收,所以是亂碼 
system("pause");
return 0;
}
 
 

2 若返回靜態變量或全局變量

能夠成爲其餘引用的初始值,便可做爲左值使用,或者右值使用。

 

指針的引用

 

指針的引用:引用是一個指針的類型。  

Type*   &name   能夠用指針的引用,作函數參數 來實現  函數參數二級指針作輸出的模型。

 
 
 
 
 
#include <iostream>
using namespace std;

struct Teacher 
{
    char name[64];
    int age;
};


//在被調用函數 獲取資源 
int getTeacher(Teacher **p)
{
    Teacher *tmp = NULL;
    if (p == NULL)
    {
        return -1;
    }
    tmp = (Teacher *)malloc(sizeof(Teacher));
    if (tmp == NULL)
    {
        return -2;
    }
    tmp->age = 33;
    // p是實參的地址  *實參的地址 去間接的修改實參的值
    *p = tmp; 
}


//指針的引用 作函數參數
int getTeacher2(Teacher* &myp)
{
    //給myp賦值 至關於給main函數中的pT1賦值
    myp = (Teacher *)malloc(sizeof(Teacher));
    if (myp == NULL)
    {
        return -1;
    }
    myp->age = 36;
}

void FreeTeacher(Teacher *pT1)
{
    if (pT1 == NULL)
    {
        return ;
    }
    free(pT1);
}

void main()
{
    Teacher *pT1 = NULL;

    //1 c語言中的二級指針
    getTeacher(&pT1);
    cout<<"age:"<<pT1->age<<endl;
    FreeTeacher(pT1);


    //2 c++中的引用 (指針的引用)
    //引用的本質 間接賦值後2個條件 讓c++編譯器幫咱們程序員作了。
    getTeacher2(pT1);

    cout<<"age:"<<pT1->age<<endl;
    FreeTeacher(pT1);

    cout << "hello..." << endl;
    system("pause");
}
 
 
常引用  
 

1 在C++中可使用變量初始const引用

 

const Type & name  = var;

const 引用讓變量擁有隻讀屬性

int a = 10;
const int &b = a;  //const 引用  使用變量a初始化

//int *p = (int *)&b;
b = 11; //err
//*p = 11; //只能用指針來改變了

 

2  使用字面量初始化 const引用 

 

//int &m = 10; //引用是內存空間的別名 字面量10沒有內存空間 沒有方法作引用
const int &m = 10;
結論:

1) const & name  至關於 const int * const name;

2) 普通引用  至關於 int* const name;

3)  當使用常量(字面量)對const 引用進行初始化時C++編譯器會爲常量分配空間,而字面量是放在代碼區(沒有內存空間),並把引用名做爲這段空間的別名。

4)使用字面量對const引用初始化後,將生成一個只讀變量。

相關文章
相關標籤/搜索