40

値渡しと参照渡しの違いを明確にしたいと思います。

絵を描きました

ここに画像の説明を入力

したがって、値渡しの場合、

同一のオブジェクトのコピーが別の参照で作成され、ローカル変数に新しい参照が割り当てられるため、新しいコピーを指す

言葉を理解する方法:「関数がその値を変更する場合、変更は、値渡しと参照渡しの両方の呼び出し関数のスコープ内にも表示されます」

ありがとう!

4

6 に答える 6

66

pass by referenceの意味を伝えないことで、多くの混乱が生じると思います。一部の人々が参照渡しと言う場合、通常は引数自体ではなく、参照されるオブジェクトを意味します。他の人は、参照渡しは、呼び出し先でオブジェクトを変更できないことを意味すると言います。例:

struct Object {
    int i;
};

void sample(Object* o) { // 1
    o->i++;
}

void sample(Object const& o) { // 2
    // nothing useful here :)
}

void sample(Object & o) { // 3
    o.i++;
}

void sample1(Object o) { // 4
    o.i++;
}

int main() {
    Object obj = { 10 };
    Object const obj_c = { 10 };

    sample(&obj); // calls 1
    sample(obj) // calls 3
    sample(obj_c); // calls 2
    sample1(obj); // calls 4
}

1 と 3 は参照渡しで、2 は値渡しであると主張する人もいます。別のグループの人々は、オブジェクト自体がコピーされないため、最後を除いてすべて参照渡しであると述べています。

ここで、参照渡しであると主張しているものの定義を描きたいと思います。それに関する一般的な概要は、参照渡しと値渡しの違い にあります。最初と最後は値渡しで、真ん中の 2 つは参照渡しです。

    sample(&obj);
       // yields a `Object*`. Passes a *pointer* to the object by value. 
       // The caller can change the pointer (the parameter), but that 
       // won't change the temporary pointer created on the call side (the argument). 

    sample(obj)
       // passes the object by *reference*. It denotes the object itself. The callee
       // has got a reference parameter.

    sample(obj_c);
       // also passes *by reference*. the reference parameter references the
       // same object like the argument expression. 

    sample1(obj);
       // pass by value. The parameter object denotes a different object than the 
       // one passed in.

私は次の定義に投票します。

引数 (1.3.1) は、呼び出された関数の対応するパラメーターが参照型を持ち、参照パラメーターが引数式 (8.5.3/4) に直接バインドされている場合にのみ、参照によって渡されます。それ以外の場合はすべて、値による受け渡しを行う必要があります。

つまり、以下は値渡しです。

void f1(Object const& o);
f1(Object()); // 1

void f2(int const& i);
f2(42); // 2

void f3(Object o);
f3(Object());     // 3
Object o1; f3(o1); // 4

void f4(Object *o);
Object o1; f4(&o1); // 5

1直接バインドされていないため、値渡しです。実装は、一時をコピーしてから、その一時を参照にバインドできます。2実装はリテラルの一時を初期化してから参照にバインドするため、値渡しです。3パラメータに参照型がないため、値渡しです。4同じ理由で値渡しです。5パラメータが参照型を取得していないため、値渡しです。次のケースは参照渡しです (8.5.3/4 などの規則により)。

void f1(Object *& op);
Object a; Object *op1 = &a; f1(op1); // 1

void f2(Object const& op);
Object b; f2(b); // 2

struct A { };
struct B { operator A&() { static A a; return a; } };
void f3(A &);
B b; f3(b); // passes the static a by reference
于 2009-01-04T11:36:01.987 に答える
9

値渡しの場合:

void func(Object o);

そして呼び出す

func(a);

スタック上にを構築し、Objectその実装内でfuncによって参照されoます。これはまだ浅いコピーである可能性があり ( と の内部は同じデータを指している可能性があります)、変更されるa可能性があります。ただし、 のディープ コピーの場合は変更されません。oaoaa

参照渡しの場合:

void func2(Object& o);

そして呼び出す

func2(a);

を参照する新しい方法を提供するだけですa。" a" と " o" は同じオブジェクトの 2 つの名前です。o内部を変更func2すると、これらの変更が呼び出し元に表示されます。呼び出し元は、" " という名前でオブジェクトを知っていますa

于 2009-01-04T07:21:43.670 に答える
6

これらすべての入力をありがとうございました!

オンラインの講義ノートからその文を引用しました: http ://www.cs.cornell.edu/courses/cs213/2002fa/lectures/Lecture02/Lecture02.pdf

最初のページ6番目のスライド

"Pass by VALUE変数の値は関数に渡されます。関数がその値を変更する場合、変更はその関数のスコープ内にとどまります。

Pass by REFERENCE変数への参照が関数に渡されます関数がその値を変更する場合、変更は呼び出し元の関数のスコープ内にも表示されます。

「」

どうもありがとうございました!

于 2009-01-04T19:59:15.700 に答える
5

あなたの質問を正しく理解しているかどうかわかりません。少しわかりにくいです。ただし、混乱する可能性があるのは次のとおりです。

  1. 参照渡しの場合、同じオブジェクトへの参照が呼び出される関数に渡されます。オブジェクトへの変更は元のオブジェクトに反映されるため、呼び出し元にはそれが表示されます。

  2. 値渡しの場合、コピー コンストラクタが呼び出されます。デフォルトのコピー コンストラクターは浅いコピーのみを行うため、呼び出された関数がオブジェクト内の整数を変更した場合、これは呼び出し元の関数には表示されませんが、関数がオブジェクト内のポインターが指すデータ構造を変更した場合、これは浅いコピーのために呼び出し元に表示されます。

私はあなたの質問を誤解したかもしれませんが、とにかく突き刺すと思いました.

于 2009-01-04T07:43:30.817 に答える
2

私が解析したところ、それらの言葉は間違っています。「関数がその値を変更する場合、変更は参照渡しの場合は呼び出し元の関数のスコープ内にも表示されますが、値渡しの場合は表示されません」と読む必要があります。

于 2009-01-04T07:21:13.407 に答える
1

「関数がその値を変更する場合、値渡しと参照渡しの両方の呼び出し関数の範囲内にも変更が表示される」という言葉の私の理解は、それらがエラーであるということです。

呼び出された関数で行われた変更は、値渡しの場合、呼び出し元の関数のスコープ内にはありません。

引用された単語をタイプミスしたか、間違っているように見える文脈から抽出されたかのどちらかです。

ソースが正しく引用されていることを確認してください。エラーがなければ、ソース資料のそのステートメントを囲むテキストをさらに提供してください.

于 2009-01-04T09:15:20.163 に答える