2012-02-15 20 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を印刷し、それらが同じアドレスだ見ることによってこれを証明することができます。あなたが何をしたか

は参照riiを変更しています。その後iを印刷すると、これが表示されます。あなたがconst int &cri = i;を作成する場合

また、比較のために、それはあなたがそれに割り当てることができません。

+0

なぜ 'const int&cri = i'は許可されていませんか?どのラインでそれを書くことができないのですか?私のためにコンパイラは、任意の場所にそのような行を挿入することができます。それとは別に、それは明確かつ簡潔な答えです! – mercury0114

+0

私はそれが許可されていないとは言いませんでした - あなたが観察したように、const以外の変数へのconst refを取っても問題ありません。私はあなたにそれを割り当てさせてはいけないと言った。つまり、OPが 'ri'で行ったように、constを使って元の変数を変更することはできない。 – Useless

+0

ああ、私はあなたが何を意味するかを見ている。 – mercury0114

3

あなたが実際に参照がバインドされているオブジェクトに値を代入参照に何かを割り当てるとき。だから、この:

ri=j; 

riiにバインドされているためだろう

i = j; 

と同じ効果があります。したがって、riのアクションはiで実行されます。

3

ri = j;の実行時に参照を再割り当てしていません。実際にjiに割り当てています。行の後にiを印刷すると、iの値が変更されたことがわかります。

6

実際に参照を再割り当てしたようです。 それは本当ですか?

いいえはありません。実際に値を再割り当てしていて、参照を再バインドしていません。

この例では、int &ri = i;を実行すると、riは、有効期限がiにバインドされています。あなたがri = j;を行うと、あなたは単にrijの値を代入しています。 riはまだiへの参照まま!あなたの代わりにi = j;

を書いていたかのように、それはあなたがうまくポインタを理解している場合、常にTは任意の型であるT* constの類推解釈のような基準を考えると同じ結果になります。

0

OPは、参照への割り当てによって参照オブジェクトを変更するように頼んでおり、これが参照ではなく参照オブジェクトを変更したと正しく言われました。 今、私は実際にリファレンスを変更する際にもっと鋭い試みを行い、潜在的に厄介なものを見つけました。 最初にコード。それは、新しく作成されたオブジェクトを参照varに再割り当てしようとした後、参照オブジェクトを参照オブジェクトに変更し、参照オブジェクトに反映されていないことを確認し、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)で参照がメモリ内のまったく同じアドレスを維持しているが、参照値(ベクトルの一部)が再割り当てされています他の場所。参考文献iはぶら下がっているかもしれません。

関連する問題