1

独立した参照が存在し、エイリアシングのように機能することを、いくつかの優れたC++チュートリアルで読みました。しかし...それは何のために作られているのだろうか。エイリアシングを使用する必要があるのはなぜですか。

その上、私には明確ではないコードの一部:

int a;
int &ref = a; // independent reference
int b = 19;
ref = b;  
cout << a << " " << ref << "\n";
ref--;  
cout << a << " " << ref << "\n";

まず、refはaへの「参照」です。コードの2行目から、refのアドレス(したがってアンペアヘッド)がaであることがわかります。次に、整数refにb(19)の値が割り当てられます。最初のcoutは、両方とも19に等しいaとrefを返します。なぜですか?整数はrefのアドレスではありませんか?次に、refをデクリメントし、最後のcoutは18を2回与えます。aとrefはデクリメントされます。

ミステリーの奇妙な解釈のみ:ここでint&はそれ自体が型であり、「整数への独立した参照」であり、この型はエイリアシングを意味します。次に、refに対して何をするにしても、同じことがaに対して行われます。

そうですか?しかし、なぜエイリアシングが必要なのですか?

4

6 に答える 6

3

次に、refに対して何をするにしても、同じことがaに対して行われます。

それはそれを見るのにかなり正確な方法です。本質的に、両方refaは同じを参照しintます。

なぜエイリアシングが必要なのですか?

参照の非常に一般的な使用法の1つは、関数に引数を渡すことです。次のことを考慮してください。

void f(const HugeStruct& data) {
 ...
}

これにより、呼び出し元は、HugeStructポインターを使用する場合よりも安価に、より適切な構文で呼び出し元にを渡すことができます。

于 2012-05-19T16:47:01.197 に答える
3

あなたは正しいです。参照は多くの点でconstポインターに似ており(たとえば、参照の値を変更すると元の変数が変更されます)、参照を初期変数以外にバインドすることはできませんが、バインドすることはできずnull、使用する構文も異なります。 (逆参照の必要はありません(*->))。これはポインタではないため、最良の説明はエイリアスです。同じ変数の別の名前と考えてください。

また、関数パラメーターとして参照を渡すと、変数のコピーは作成されず(ポインターを使用して値を指すように)、参照への変更は元の変数に反映されます。

const参照には、バインドされているconst参照がスコープ外になるまで、一時値が通常の存続期間を超えて存続できるようにする特別な規則もあります。

于 2012-05-19T16:48:14.877 に答える
2

あなたの例ではあまり意味がありません。しかし、これを考慮してください:

int & ri = expensive_function_call(args)->some_map[calculate_the_key()].first;
if (ri > 6) ri = 6;

vs

if (expensive_function_call(args)->some_map[calculate_the_key()].first > 6)
    expensive_function_call(args)->some_map[calculate_the_key()].first = 6;

もちろん、ポインタを使用することもできます。

int * pi = &expensive_function_call(args)->some_map[calculate_the_key()].first;
if (*pi > 6) *pi = 6;

エイリアス(参照またはポインター)を使用することにより、コードがほぼ半分に削減されるだけでなく、実行時にプログラムが実行する必要のある作業も半分に削減されます(少なくともコンパイラーが最適化を開始する前に)。

于 2012-05-19T16:46:47.837 に答える
2

コードの2行目から、refのアドレス(したがってアンパサンド)がaであることがわかります。次に、整数refにbの値が割り当てられます。

参照がどのように機能するかを理解していないと思います。

int a;
int &ref = a;

最初の行はオブジェクトを割り当てintます。このオブジェクトは、ローカル変数を使用して参照できますa

2行目は、ref同じintオブジェクトのエイリアスにする効果があります。aまたはを使用してオブジェクトに変更を加えることができますが、オブジェクトrefは1つだけintです。

于 2012-05-19T16:49:32.527 に答える
1

関数呼び出しが含まれていない場合でも、alisesの良い使用法があります。

名前を簡略化するために使用できます

MyComplicatedStruct x;
int &ref = x.array[17].anotherarray[3];
// Do stuff with 'ref'

その整数値を使用するたびにそれを綴らなければならないのは苦痛です(そしてエラーが発生しやすいです!)。

もう一つの例:

int myFirstValue = 1;
int MyOtherValue = 2;

while(true) {
    int &value = (SomeComplicatedTest() ? myFirstValue : myOtherValue);
    // do stuff with 'value'
}

これは、参照なしで行うのも苦痛(そしてエラーが発生しやすい)になります。

于 2012-05-19T17:06:13.817 に答える
1

あなたの質問には多くの根本的な虚偽の記述があるので、あなたはC++に関する良い本を手に取ってそれを読む必要があります。

まず、aはrefのアドレスではありません。&コードの最初の行で演算子 を使用する場合:のアドレスをにint &ref = a 設定していません。既存の整数のエイリアスである新しい変数、つまり、への明示的な参照を作成しています。これはそれ自体の演算子/操作であり、アドレスやポインターとは何の関係もありません(実際にはそうではありません)。refaa

refその後、読み取りまたは書き込みを行うときはいつでも、に書き込みを行っているかのようになります。refは別の言い方aになりました。これに対して行う操作(アドレスの取得を含む)はすべてに転送されaます。

于 2012-05-19T16:50:17.330 に答える