4

私はマイヤーズの本を読んでいて、参照/ポインター対値で戻る際の項目に出くわしました。重要なのは、たとえば関数が次のような場合です。

ClassA& AddSomething(ClassA classA)
{
  ClassA tempClassA;
  //... do something on tempClassA
  return tempClassA;
}

スタック上に作成されたオブジェクトへの参照を返しているため、これは機能しません。関数が実行されたため、これは無効になっています。

彼は2つの解決策を与えます:

  1. 関数内でローカル静的ClassAを使用します。これには問題がありますが、少なくともオブジェクトが存在することを確認できます。
  2. オブジェクトとして返す:

    ClassA AddSomething(ClassA classA)
    {
      ClassA tempClassA;
      //... do something on tempClassA
      return tempClassA;
    }
    

今私がする場合:

ClassA obj1;
ClassA obj2 = AddSomething(obj1);

私の混乱は、この行を実行するときです:

  1. tempClassAの「コピー」が作成され、ClassAのコピーコンストラクターに渡されます(obj2を初期化するため)?また
  2. コピーコンストラクターは参照を取得するため、tempClassAはClassAのコピーコンストラクターに渡されます。

したがって、基本的に、コピーコンストラクターに渡されるのは、tempClassA(関数内のスタックで作成された)への参照またはtempClassAのコピーへの参照です。

また、私が持っている別の質問は、関数のローカル変数の参照を取得した場合、その場合、ローカル変数は削除されないことを読みました。例えば、

ClassA & classRef = AddSomething(obj1);

この場合、AddSomething()が参照を返す場合、ローカル変数が保持されるため、classRefは削除された参照を指していません。私はこれを正しく理解しましたか?

4

3 に答える 3

5

最悪の場合、その通りです。tempClassAのコピーがコピーコンストラクタに渡されます。ただし、コンパイラはそのコピーを削除して、結果をインプレース形式で作成できtempClassAます。これは「戻り値の最適化」またはRVOとして知られています。私はこれを行わないコンパイラを知りません。

于 2012-08-30T14:10:12.177 に答える
2

オブジェクトが値によって返される場合、2つのコピーが実行されます。1つはローカル変数から戻り値へ、もう1つは戻り値からターゲットオブジェクトへのコピーです。ただし、実装では、これらのコピーの一方または両方を削除できます。これは、最初のケースでは戻り値の最適化(RVO)と呼ばれ、2番目のケースではコピーの省略と呼ばれます。

Object some_function() {
    return Object();    // copy Object() into return value; candidate for RVO
}
Object another_function() {
    Object obj;
    return obj;         // copy obj into return value; candidate for NRVO
}
Object result = some_function();   // copy return value into result; candidate for copy elision

上記の2番目の関数は、名前付き戻り値の最適化と呼ばれるRVOの改良タイプの候補です。RVOの最も単純な形式は、戻り値をインプレースで構成するreturnステートメントにのみ適用されます。

2番目の質問に関して、有効期間の延長は、値によって返されるオブジェクトへのconst参照にのみ適用されます。2番目の質問のコードは、オブジェクトの存続期間を延長しません。詳細については、一時オブジェクトの返却とconst参照へのバインドを参照してください。

于 2012-08-30T14:12:03.620 に答える
0

参照によって関数ローカル変数を返すことはできません。const参照を使用して次のように戻り値をキャプチャした場合でも、機能しません。

const ClassA& classRef = AddSomething(obj1);

AddSomethingが参照によってローカルオブジェクトを返す場合、classRefが参照するまでに、存在しないオブジェクトへのぶら下がっている参照になるためです。

于 2012-08-30T14:38:26.577 に答える