1. ホーム
  2. c++

[解決済み] shared_ptrとraw pointersはいつ使うのか?

2023-07-01 18:27:35

質問

class B;

class A
{
public:
    A ()
        : m_b(new B())
    {
    }

    shared_ptr<B> GimmeB ()
    {
        return m_b;
    }

private:
    shared_ptr<B> m_b;
};

Bが意味的にAの寿命の外に存在してはならないクラス、すなわちBがそれ自体で存在することは全く意味がないクラスだとしましょう。 べきです。 GimmeB を返します。 shared_ptr<B> または B* ?

一般的に、C++のコードでスマートポインタの代わりに生のポインタを使用することを完全に避けることは良い習慣ですか?

私は、次のような意見を持っています。 shared_ptr これは、関数がメモリを確保し、そこにデータを格納して返すようなケース以外で、呼び出し側と呼び出し側の間で、呼び出し側がそのデータに対して責任があるということが理解されている場合、非常に稀だと思います。

どのように解決するのですか?

あなたの分析は非常に正しいと思います。このような場合、私も素直に B* を返すか、あるいは [const] B& であっても、オブジェクトが決してNULLにならないことが保証されていれば

スマートポインターを熟読する時間があったので、多くのケースで何をすべきかを教えてくれるいくつかのガイドラインにたどり着きました。

  • 呼び出し側で寿命が管理されるオブジェクトを返す場合、そのオブジェクトに対して std::unique_ptr . 呼び出し元はそれを std::shared_ptr に割り当てることができます。
  • 返送する std::shared_ptr それは、呼び出し元に対して、リソースを元々管理していたオブジェクトの寿命よりも、ポインタ先のオブジェクトの寿命を長くすることを示すためです。ファクトリーから共有ポインタを返すことも例外ではありません。 std::enable_shared_from_this .
  • が必要になることはほとんどありません。 std::weak_ptr の意味を理解したい場合を除き、ほとんど必要ありません。 lock メソッドの意味を理解したい場合を除きます。これにはいくつかの使い道がありますが、稀なことです。あなたの例では、もし A オブジェクトの寿命が呼び出し元の観点から決定論的でなかった場合、これは考慮すべきことだったでしょう。
  • 呼び出し元がその寿命を制御できない既存のオブジェクトへの参照を返す場合、ベアポインタまたは参照を返します。そうすることで、呼び出し元にオブジェクトが存在し、その寿命に気を配る必要がないことを伝えることができます。を使用しないのであれば、参照を返すべきです。 nullptr の値を使用しない場合は、参照を返すべきです。