1. 程式人生 > >C++ 引用& 和 右值引用&& (1)

C++ 引用& 和 右值引用&& (1)

 我們先來簡單介紹下&引用:

C和C++使用&符號來只是變數的地址。C++給&符號賦予了另一個含義,將其來宣告引用。

例如,要將rodents作為rats變數的別名,可以這樣做:

int rats;
int & rodents = rates;

其中,&不是地址運算子,而是型別識別符號的一部分。上訴引用宣告允許將rats和rodents互換——它們指向相同的值和記憶體單元。

必須在宣告引用時將其初始化,而不能向指標那樣,先宣告,再賦值。

舉個例子:

// secref.cpp -- defining and using a reference
#include <iostream>
int main()
{
    using namespace std;
    int rats = 101;
    int & rodents = rats;   // rodents is a reference

    cout << "rats = " << rats;
    cout << ", rodents = " << rodents << endl;

    cout << "rats address = " << &rats;
    cout << ", rodents address = " << &rodents << endl;

    int bunnies = 50;
    rodents = bunnies;       // can we change the reference?
    cout << "bunnies = " << bunnies;
    cout << ", rats = " << rats;
    cout << ", rodents = " << rodents << endl;

    cout << "bunnies address = " << &bunnies;
    cout << ", rodents address = " << &rodents << endl;
    // cin.get();
    return 0; 
}

輸出:

rats=101,rodents=101

rats address=0x00065fd44,rodents address= 0x00065fd44

bunnies=50,rate=50,rodents=50

rats address=0x00065fd48,rodents address= 0x00065fd44

也就是說,rats=bunnies 意味著“ 將bunnies變數的值付給rat變數 ”。簡而言之,可以通過初始化宣告來設定引用,但是不能用賦值來設定。

假設程式設計師試圖這樣做:

int rats=101;
int *pt =&rats;
int &rodents=*pt;
int bunnies=50;
pt =&bunnies;

將rodents初始化為*pt使得rodents指向rats。接下來將pt改為指向bunnies,並不能改變這樣的事實,即rodents引用的是rats。

將引用用作函式引數

// cubes.cpp -- regular and reference arguments
#include <iostream>
double cube(double a);
double refcube(double &ra);
int main ()
{
    using namespace std;
    double x = 3.0;

    cout << cube(x);
    cout << " = cube of " << x << endl;
    cout << refcube(x);
    cout << " = cube of " << x << endl;
    // cin.get();
    return 0;
}

double cube(double a)
{
    a *= a * a;
    return a;
}

double refcube(double &ra)
{
    ra *= ra * ra;
    return ra; 
}

 輸出:

27=cube of 3

27 = cube of 27

如果程式設計師的意圖是讓函式使用傳遞給它的資訊,而不對這些資訊進行修改,同時又想使用引用,則應使用常量引用。 

double refcube(const double &ra);

如果這樣做,當編譯器發現程式碼修改了ra的值,將報錯。

如果實參與引用引數不匹配,C++將生成臨時引數。 當前,僅當引數為const引用時,C++才允許這樣做(c++ primer plus 264頁)。因為假如型別不匹配的話,將建立臨時引數,使用臨時引數的資料改變不會影響傳入的資料。換句話說,如果接受引用引數的函式的意圖是修改作為引數傳遞的變數,則建立臨時變數將阻止這種意圖的實現。

注意:如果函式呼叫的引數不是左值或與相應的const引用引數的型別不匹配,則C++將建立型別正確的匿名變數,將函式呼叫的引數的值傳遞給該匿名變數,並讓引數來引用該變數。

舉個例子:

void swap(int &a,int &b)
{
    int temp;

    temp=a;
    a=b;
    b=temp;
}

long a=3,b=5;
swap(a,b);

這裡的a,b與傳入函式引數的a,b型別不匹配,因此編譯器將建立兩個臨時int變數,將它們初始為3和5,然後交換臨時變數的內容,而a和b保持不變。

然後我們來看下右值引用&&

引用右值的只要目的是實現移動定義。