2012-02-15 51 views
40

我在任何地方都看過參考文件必須在那裏進行初始化,並且不能再次重新初始化。我們可以在C++中重新分配參考嗎?

爲了測試我的理解,我寫了下面的小程序。似乎我已經成功地重新分配了一個參考。有人可以向我解釋我的程序中究竟發生了什麼?

#include <iostream> 
#include <stdio.h> 
#include <conio.h> 

using namespace std; 

int main() 
{ 
    int i = 5, j = 9; 

    int &ri = i; 
    cout << " ri is : " << ri <<"\n"; 

    i = 10; 
    cout << " ri is : " << ri << "\n"; 

    ri = j; // >>> Is this not reassigning the reference? <<< 
    cout << " ri is : " << ri <<"\n"; 

    getch(); 
    return 0; 
} 

代碼編譯罰款和輸出是如我所料:

ri is : 5 
ri is : 10 
ri is : 9 

回答

42

ri = j; // >>> Is this not reassigning the reference? <<<

沒有,ri仍然是i參考 - 您可以通過打印&ri&i,看它們是同一個地址證明了這一點。

你所做的是修改i參考ri。打印i之後,你會看到這個。

此外,作爲比較,如果您創建一個const int &cri = i;它不會讓你分配。

+0

爲什麼'const int&cri = i'不允許?你不能寫哪一行?對我來說編譯器的原因允許在任何地方插入這樣的行。除此之外,這是一個清晰而簡潔的答案! – mercury0114 2016-04-22 05:30:34

+0

我沒有說這是不允許的 - 正如你所觀察到的,對非const變量採取const ref是沒有問題的。我說它不會讓你分配給that_,這意味着你不能通過const ref來改變原來的變量,就像OP用'ri'做的那樣。 – Useless 2016-04-22 08:22:29

+0

哦,對,我現在明白你的意思了。 – mercury0114 2016-04-22 08:40:06

3

當你分配東西的參考,你居然指定值的引用綁定到該對象。所以這個:

ri=j; 

具有作爲

i = j; 

同樣的效果會有,因爲ri勢必i。因此,ri上的任何操作都會在i上執行。

3

執行ri = j;時,您不會重新分配參考。你實際上將j分配到i。嘗試在行後打印i,您會看到i更改了值。

6

看起來好像我實際上已經成功地重新分配了一個參考。 這是真的嗎?

,你還沒有。你實際上正在重新分配這個值,而你並沒有重新引用這個參考。

在你的例子中,當你做int &ri = i;時,ri在它的生命週期內綁定到i。當您執行ri = j;時,只需將j的值分配給ri即可。 ri仍然是對i的參考!並且它導致同樣的結果,如果你已經代替書面i = j;

如果你理解了指針好,然後一直認爲作爲參考的T* const的類推解釋,其中T是任何類型的。

0

OP要求通過賦值給引用來更改引用的對象,並且非常正確地告知這改變了引用對象而不是引用。 現在我做了一個更真實的嘗試,真正改變了參考,發現了潛在的討厭的東西。 首先是代碼。它試圖重新分配引用var一個新創建的對象,然後改變引用aka引用的對象,發現這並不反映在明顯引用的對象中,並得出結論:我們可能在C++中有一個懸掛指針的情況。對於匆忙組成的代碼抱歉。

using namespace std; 
vector<int>myints; 

auto &i = myints.emplace_back(); // allocate and reference new int in vector 
auto myintsaddr = &myints; auto myintfrontaddr = &myints.front(); // for future reference 
i = 1;        // assign a value to the new int through reference 
cout << hex << "address of i: 0x" << &i << " equals " << "address of 
myints.back(): 0x" << &myints.back() << '.' << endl; // check reference as expected 
i = myints.emplace_back();  // allocate new int in vector and assign to old reference variable 
i = 2;       // give another value to i 
cout << "i=" << i << ", myints={" << myints[0] << ", "<< myints[1] << '}' << endl; // any change to potentially referenced objects? 
cout << hex << "&i: 0x" << &i << " unequal to " << "&myints.back(): 0x" << &myints.back() << " as well as &myints.front(): 0x" << &myints.front() << endl; 
cout << "Myints " << (myintsaddr== &myints?"not ":"") << "relocated from " << myintsaddr << " to " << &myints << endl; 
cout << "Myints front() " << (myintfrontaddr == &myints.front() ? "not " : "") << "relocated from " << myintfrontaddr << " to " << &myints.front() << endl; 

輸出:

address of i: 0x0063C1A0 equals address of myints.back(): 0x0063C1A0. 
i=2, myints={1, 0} 
&i: 0x0063C1A0 unequal to &myints.back(): 0x0063F00C as well as &myints.front(): 0x0063F008 
Myints not relocated from 0039FE48 to 0039FE48 
Myints front() relocated from 0063C1A0 to 0063F008 

結論:至少在我的情況(VS2017)參考已保存在存儲器中完全相同的地址,但是所引用的值(載體的一部分)已重新分配別處。參考我可能會晃來晃去。

相關問題