24

スマート ポインターは一般に小さいため、値渡しは問題ありませんが、スマート ポインターへの参照の受け渡しに問題はありますか。むしろ、これを行ってはならない特定のケースがありますか?

私はラッパー ライブラリを作成しており、いくつかのクラスは基になるライブラリでスマート ポインター オブジェクトをラップしています... 私のクラスはスマート ポインターではありませんが、API は現在スマート ポインター オブジェクトを値渡ししています。

例: 現在のコード:

void class::method(const AnimalPtr pAnimal) { ... }

になる

void class::method(const MyAnimal &animal){...}

MyAnimalカプセル化する新しいラッパー クラスはどこにありますかAnimalPtr

Wrapper クラスがいつの日かスマート ポインターをラップする以上に成長しないという保証はありません。そのため、値渡しは緊張します。

4

2 に答える 2

30

ほとんどの場合、値ではなく参照によって共有ポインタを渡す必要があります。a のサイズstd::shared_ptrは小さいですが、コピーのコストにはアトミック操作が含まれます (概念的には、アトミックなインクリメントとコピーの破棄時のアトミックなデクリメントですが、非アトミックなインクリメントを行うことができる実装もあると思います)。

それ以外の場合、たとえば、コピーは移動である必要があり、オブジェクトの所有権が関数に転送されることを明確に文書化std::unique_ptrするため、値渡しを好む場合があります (所有権を転送したくない場合は、ではなく、実際のオブジェクトへの参照)。std::unique_ptr

それ以外の場合、走行距離は異なる場合があります。スマート ポインターのコピーのセマンティクスと、そのコストを支払う必要があるかどうかを認識する必要があります。

于 2013-06-28T15:53:45.680 に答える
3

コンストラクタへの場合を除き、参照によってスマート ポインタを渡すことは問題ありません。コンストラクターでは、元のオブジェクトへの参照を格納することができますが、これはスマート ポインターの規約に違反しています。これを行うと、メモリが破損する可能性があります。コンストラクターが現在参照を保存していなくても、コードが変更され、後で変数をより長く保持する必要があると判断した場合に見逃しやすいため、私はまだ用心深いでしょう。

通常の関数では、初期化中に参照を設定する必要があるため、関数パラメーターを参照としてどこにも格納できません。参照を長寿命の非参照変数に割り当てることもできますが、それはコピーになるため、その有効期間が適切に長くなります。したがって、どちらの場合も、呼び出し元の関数が解放した可能性がある場合、それを保持することはできません。この場合、参照によってパフォーマンスがわずかに向上する可能性がありますが、ほとんどの場合、それに気付くつもりはありません。

つまり、コンストラクターは常に値渡しです。他の関数は、必要に応じて参照渡しします。

于 2013-06-28T17:00:30.327 に答える