4

状況によっては、値を選択するか参照セマンティクスを選択するかについての感覚がありません(まだ、私は願っています)。適用できる経験則はありますか?

私は通常、組み込みデータ型(char、int、bool、doubleなど)以外のすべての参照を選択します。ただし、関数から参照を返すことができない場合があるため、ポインターを使用する必要があります。次の関数はこの例です。

Foo bar()
{
    Foo f;
    f.do_stuff();
    return f;
}

boost :: shared_ptrを使用してFooオブジェクトを保存しますが、オブジェクトの操作が非常に見苦しくなります。私は現在、10個を超える要素がほとんどないdequeを返す関数を調べています(これは私が想定していることですが、確認する方法はありません)。これを値で返すのは大丈夫でしょうか?私の考慮事項は時期尚早の最適化の場合ですか?

4

5 に答える 5

3

いずれの場合も、参照またはポインターによってスタックに割り当てられたもの(つまり、ここではfなどのローカル変数)を返さないでください。

于 2010-12-12T12:19:26.193 に答える
3

ほとんどのコンパイラは余分なコピーを最適化するため、値による戻りは問題ありません(これは、戻り値の最適化、または名前付き戻り値の最適化と呼ばれます)。

しかし、慣用的な方法は

void bar(Foo& out)
{
   out.do_stuff();
}
于 2010-12-12T12:21:56.617 に答える
0

あなたはいつでもこれを行うことができます:

Foo& bar(Foo& f)
{
    f.do_stuff();
    return f;
}

そして、次のように使用します。

Foo f;
bar(f);

ここでの欠点は、 がオブジェクトbar()の新しいコピーを受け取ることを保証できないことです。Fooそれが重要な場合は、次のように変更する必要があります。

Foo& bar(Foo& f)
{
    f = Foo();
    f.do_stuff();
    return f;
}

ただし、新しいコピーを取得すると、不要な初期化が発生します。fまたは、前に調べdoSomething()て、期待どおりでない場合は例外をスローすることもできます。

于 2010-12-12T12:22:18.023 に答える
0

変数またはオブジェクトの状態を維持したい場合 (つまり、呼び出されたルーチンによって変数/オブジェクトに対して何らかの処理が行われた後、呼び出し元のルーチンに同じ変数を返す場合)、および大きなデータをに渡す場合にも、参照を使用します。そうしないと、大容量データの二重コピーが発生します。

また、オブジェクトのビットごとのコピーを防止する必要がある場合には、クラスのコピー コンストラクターをプライベートにします。

于 2010-12-12T12:50:01.433 に答える
-1

私の通常のルールは次のとおりです。

  1. 常に値渡しを使用します。

    シンプルですね。参照吸う。それらは決して導入されるべきではありませんでした。

  2. 「データ構造のような値」がある場合は、それを渡します。「データ構造のようなオブジェクト」がある場合は、ポインターを渡します(参照セマンティクス、値渡し)。

    通常、型が何であるか (値またはオブジェクト) は明らかです。あなたがそれを変異させることができれば、それはオブジェクトです。

于 2010-12-12T15:28:37.440 に答える