トップページ – Modern C++編 C++編](../../index.html) – 第4章
問題① std::unique_ptr と std::shared_ptr は、どのような方針で使い分けますか?
両者の違いをメンバ関数の違いとか、引数の違いとかで考えるのではなく、本質的な目的が異なることを認識しましょう。std::unique_ptr はリソースを独占的に管理するもの。std::shared_ptr はリソースを共有して管理するものです。
たとえば、あるリソースを使用するオブジェクトが複数あるとして、それぞれのオブジェクトが生存している期間がばらばらなのであれば、最後のオブジェクトが破棄されるまで、リソースは生存し続けていなければなりません。これは、複数のオブジェクトがリソースを共有する形であり、std::shared_ptr を使わなければなりません。
基本的には、std::shared_ptr を使う必要がないとき、つまりリソースを共有しないにはいつも、std::unique_ptr を使うようにします。参照カウントに絡むコストが掛からないため、std::unique_ptr の方が効率的ですし、本編で述べたとおり、std::unique_ptr から std::shared_ptr への変換は容易に行えます。
問題② 次のように宣言された3つの関数があります。
void f1(std::shared_ptr<MyClass> p);
void f2(const std::shared_ptr<MyClass>& p);
void f3(std::shared_ptr<MyClass>&& p);
それぞれの関数に、std::shared_ptr のオブジェクトを渡すと、どのような処理が行われるか説明してください。
f1関数は、std::shared_ptr オブジェクトのコピーを渡すことになります。そのため、同じリソースを共有する新たな std::shared_ptr が作られ、参照カウントは +1 されます。
この実装は、他の2つの実装に比べて、効率面で劣っています。新たな std::shared_ptrオブジェクトを作らなければならず、参照カウントをインクリメントする処理が加わります。
特に、参照カウントの操作は、並列処理に備えて同期制御が行われているため、+1 するだけというイメージに反して、処理負荷は大きめです。
f2関数では、std::shared_ptr のオブジェクトの const参照が渡されています。これは、std::shared_ptr そのものではないので、コピーが取られるわけではなく、参照カウントも変化しません。したがって、f1関数よりも効率的です。
f3関数では、std::shared_ptr のオブジェクトをムーブします。そのため、呼び出し元のオブジェクトは使用できなくなりますから、f1関数や f2関数とは大きく挙動が異なります。ムーブの場合は、ムーブ元は所有権を放棄するため、参照カウントの値は変化しません。そのため、f1関数よりも処理は高速に行われることが期待できます。
新規作成。
Programming Place Plus のトップページへ
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
RSS | 管理者情報 | プライバシーポリシー |