9

私は C++ が初めてで、いくつか質問があります。これはその 1 つです。

変数へのポインターではなく、変数のコピーを渡すために、1 つまたは複数のパラメーターを受け取る関数を使用しているときに、そのパラメーターが関数呼び出しの前に常に変数に格納されることがわかっている場合、何らかの理由がありますか? ?

私はパフォーマンスの面で話しています。構造体全体のコピーを渡すには、単なるポインター (4 バイト) よりもはるかに多くのリソースが必要になるように思えます。

4

6 に答える 6

12

ポインターを渡すよりもコピーを渡す方がコストがかからない方法がいくつかあります。

  1. オブジェクトがポインタ以下です。値に直接アクセスすることは、ポインターを逆参照するよりも常に高速です。
  2. 構造体は、コンパイラによってスタックに置かれるほど小さいです。この場合、構造内の値へのアクセスは、間接的なインデックス付きアドレッシング モードではなく、インデックス付きアドレッシング モードによって行われます。前者は一般的に高速です。

参照ではなくコピーを渡したい理由は他にもあります。つまり、関数が呼び出し元に反映されない構造に変更を加える場合です。これは一般的に不適切な方法ですが、パラメーターを値渡しにすることで、呼び出し元のビューが誤って変更されないようにすることができます。

ここで、おそらく聞きたくない答えの一部について説明します。通常、それほど大きな違いはありません。プログラムのセマンティクスに最も適したパラメーターの受け渡し方法を使用してください。後で特定の領域にパフォーマンスのボトルネックがあることがわかった場合は、その領域のパフォーマンスの改善に集中してください。最適化しすぎないでください!

于 2008-11-04T11:34:16.267 に答える
10

オブジェクトをポインター (または参照) で渡す場合と、同じオブジェクトのコピーを渡す場合では、セマンティクスが異なります。オブジェクトに加えた変更を関数呼び出しの外部に反映させたい場合は、参照セマンティクスが必要です。それ以外の場合は、値セマンティクスが必要です。

一般に、値のセマンティクスは、値を値または const 参照で渡すことによって表現できます。

void value_semantics(my_obj obj);
void value_semantics(const my_obj& obj);

ただし、 const 参照方法にはいくつかの欠点もあります。コンパイラが行う可能性のあるいくつかの最適化を防ぎます。これは、単純なコンストラクターを持つオブジェクトのエイリアシングの問題のために、余分なレベルの間接参照 (参照がポインターとして実装される) が回避の利点を上回る可能性があるためです。コピー。

参照セマンティクスを取得するには、参照渡しまたはポインター渡しのいずれかを選択できます。C++ では、参照はポインターよりも自然であると他の人が既に述べているため ( operator のアドレスを使用する必要はありません&)、ポインターの唯一の本当の利点は次のとおりです。 NULL 値を有効にする場合。

経験則として、自明でないクラスの場合は const 参照で渡す必要があり、それ以外の場合は値で渡す必要があります。

于 2008-11-04T11:35:32.347 に答える
4

ポインターは、呼び出し先がオブジェクトを変更できるようにするため、バグの可能性があります。ポインターは 0 になる可能性があり、これはクラッシュを引き起こす傾向があり、これによりあらゆる場所で 0 ポインターをテストする必要が生じます。これは煩わしい場合があります。C++ 参照を使用constすると、可能な場合は宣言され、これらの問題の両方を回避できます。

于 2008-11-04T11:25:35.580 に答える
4

ポインタの使用は避けてください。IN パラメータの場合は定数参照を使用してください。そうでない場合は、IN OUT パラメータの参照のみを使用してください。

于 2008-11-04T11:31:48.533 に答える
2

主な問題はパフォーマンスではなく、セマンティクス、および関数が構造内のデータを変更するかどうかです。

関数が構造を変更する場合、ポインターを渡すと、呼び出し元は構造内の変更されたデータを確認できます。この場合、コピーを渡すのは間違っている可能性があります。これは、関数がコピーを変更してから (おそらく) 破棄されるためです。もちろん、関数がデータを変更する可能性はありますが、変更を望まない場合は、元の値を変更から保護するためにコピーを作成するのが適切です。

関数が構造を変更しない場合、値は読み取られるだけなので、値をコピーする理由はありません。

ポインターを構造体に渡すという概念に慣れていない場合は、C および C++ で構造体を処理する一般的な方法であるため、ある程度練習する必要があります。

パフォーマンスに関する限り、構造をコピーするのはより多くの作業ですが、物事のスキームではかなりマイナーです。最初にコードのセマンティクスに注意してください。

于 2008-11-04T11:31:00.890 に答える
1

参照がより一般的であり、変更されない場合は const 参照です。

于 2008-11-04T11:25:11.323 に答える