26

どのような状況で、参照渡しを優先する必要がありますか?値渡し?

4

8 に答える 8

40

値渡しよりも参照渡しを使用する必要がある主なケースは4つあります。

  1. 引数を変更する必要がある関数を呼び出す場合は、参照渡しまたはポインター渡しを使用してください。それ以外の場合は、引数のコピーを取得します。
  2. 大きなオブジェクトをパラメーターとして受け取る必要のある関数を呼び出す場合は、そのオブジェクトの不要なコピーを作成して効率を大幅に低下させないように、const参照で渡します。
  3. 定義上参照を取る必要があるコピーまたは移動コンストラクターを作成している場合は、参照渡しを使用します。
  4. ポリモーフィッククラスを操作する関数を作成している場合は、スライスを回避するために、参照渡しまたはポインター渡しを使用してください。
于 2011-02-13T19:35:59.150 に答える
7

次のようないくつかの考慮事項があります。

パフォーマンス

値で渡すとデータがコピーされるため、大きなデータ構造を値で渡すとパフォーマンスが低下する可能性があります。参照による受け渡しは、参照(基本的にはアドレス)のみをデータに渡します。大規模なデータ構造の場合、これによりパフォーマンスが大幅に向上します。小さいデータ構造(intなど)の場合、参照渡しはパフォーマンスを阻害する可能性があります。

変更

値を渡すとデータがコピーされるため、ターゲットコードがそのコピーを変更しても、元のデータには影響しません。参照による受け渡しはデータのアドレスのみを渡すため、その参照に対して行われた変更は呼び出し元のコードに「表示」されます。

于 2011-02-13T19:33:30.953 に答える
2

はい。

ネイティブタイプのように、直接渡すのが効率的であるほど小さいものの値を渡します。それ以外の場合は、pass by(const)参照を使用します。

難しい部分は、どちらにも適用できるテンプレートを作成することです(この場合、通常は参照渡しを使用します-大きなオブジェクトを値で渡す場合の潜在的なペナルティは、渡すときに参照で渡す場合の潜在的なペナルティよりもはるかに悪いです値で優先されます)。

編集:もちろん、これは、必要なセマンティクスがどちらかを許可する状況を想定しています-明らかに、ポリモーフィックオブジェクトのようなもので作業している場合は、ポインタまたは参照を使用する必要があるため、実際の「設定」は含まれません正しい動作を取得します。

于 2011-02-13T19:34:16.960 に答える
2

他の人はすでにあなたの質問に十分によく答えているので、私は重要な点を追加したいと思います:

クラスにcopy-constructorがない場合、値を渡す選択肢はありません。public参照で渡す必要があります(またはポインターを渡すことができます)。

次のプログラムはコンパイルされません。

class A
{
public:
     A(){}
private:
     A(const A&) {}
};

//source of error : pass by value
void f(A ) {}

int main() {
        A a;
        f(a);
    return 0;
}

エラー:

prog.cpp:関数内'int main()':
prog.cpp:10:エラー:'A :: A(const A&)'はプライベート
prog.cpp:18:エラー:このコンテキスト内
prog.cpp:18:エラー:'void f(A)'の引数1を初期化しています</ p>

ideoneで自分を見てください:http ://www.ideone.com/b2WLi

ただし、関数fを参照で渡すと、正常にコンパイルされます:http ://www.ideone.com/i6XXB

于 2011-02-13T19:39:54.880 に答える
1

質問にCとC++の両方のタグを付けました。

したがって、この機能をサポートするC ++での参照渡しの使用を検討し、この機能をサポートしないCでの使用を検討しないことをお勧めします。

于 2011-02-13T19:40:58.367 に答える
1

簡単なルールは次のとおりです。

pass by reference when the value is large.

他の答えは素晴らしいです。これを最も単純にしようとしています。

于 2022-01-22T17:02:54.293 に答える
0

参照渡しは、以下の条件でのみ呼び出すことができます。

参照渡しは、引数をコピーしないため、値渡しよりも効率的です。仮パラメータは、引数のエイリアスです。呼び出された関数が仮パラメーターの読み取りまたは書き込みを行う場合、実際には引数自体の読み取りまたは書き込みが行われます。

参照渡しと値渡しの違いは、呼び出された関数で参照によって渡された引数に加えられた変更は呼び出し元の関数に影響を与えるのに対し、呼び出された関数で値によって渡された引数に加えられた変更はできないことです。呼び出し元の関数に影響を与えます。

呼び出し元の関数で引数の値を変更する場合は、参照渡しを使用します。それ以外の場合は、値渡しを使用して引数を渡します。

参照パスとポインタパスの違いは次のとおりです。

そのポインタはNULLまたは再割り当てできますが、参照はできません。NULLが有効なパラメーター値である場合、またはポインターを再割り当てする場合は、ポインター渡しを使用してください。それ以外の場合は、定数または非定数の参照を使用して引数を渡します。

于 2019-01-03T19:00:35.543 に答える
-3

ポインターは参照ですが、C ++の「参照」は通常、SomeType&のパラメーターにタグを付ける方法を指します。

絶対にやるべきではありません。適切な唯一の場所は、さまざまな事前定義された演算子を実装するために必要な魔法の構文です。さもないと:

  • 参照によってパラメーターを渡すことは絶対にしないでください。ポインターを渡すことはできません。そうしないと、コードレビューがほとんど不可能になります。参照渡しでは、呼び出しを調べて、どのパラメーターが変更されると予想されるかを判断することは不可能です。

  • また、参照によってパラメータを渡してはなりません。繰り返しますが、これはメタ最適化を実行していることを意味します。常に値渡しを行う必要があります。そうしないと、オブジェクトの内部を覗き見し、その実装を調べて、何らかの理由で参照渡しが望ましいと判断することになります。

すべてのC++クラスは、値で渡すために必要なすべてのコピーおよび代入コンストラクターとオーバーロードを実装する必要があります。それ以外の場合は、クラスの実装の詳細からプログラマーを抽象化するという役割を果たしていません。

于 2011-02-13T19:55:58.593 に答える