11

shared_ptr メンバー変数を初期化する場合:

// .h
class Customer
{
public:
  Customer();

private:
  std::shared_ptr<OtherClass> something_;
}

// .cpp
Customer():
  something_(new OtherClass())
{
}

対。

Customer():
  something_(std::make_shared<OtherClass>())
{
}

make_shared バージョンは使用できますか? いつも最初のバージョンが表示されるようですが、どちらが優先されますか?

4

2 に答える 2

14

が許可されないmake_sharedのは、次の場合のみです。

  1. 他の誰かによって割り当てられたネイキッド ポインターを取得し、shared_ptr. これは、C API とのインターフェイスの場合によく見られます。
  2. 呼び出したいコンストラクターがパブリックでない場合 (make_sharedパブリック コンストラクターのみを呼び出すことができます)。これは、ユーザーにファクトリからのオブジェクトの作成を強制するファクトリ関数で発生する可能性があります。

    ただし、これを回避する方法があります。プライベート コンストラクターを使用する代わりに、パブリック コンストラクターを使用します。ただし、クラスへのプライベートアクセスを持つ人だけが構築できるタイプのコンストラクターを作成します。そうすれば、そのオブジェクト タイプで呼び出すことができるmake_sharedのは、クラスへのプライベート アクセスを持つ人だけになります。

はい、これを行うことができます。

于 2012-04-23T23:51:52.190 に答える
5

この場合、使用をmake_shared許可するだけではなく、使用した方がよいでしょう。new を使用すると、Customer 用のメモリがどこかに割り当てられ、次に shared_ptr 用のメモリが別の場所に割り当てられ、強い参照と弱い参照の両方が格納されます (弱いポインタと共有ポインタ用)。を使用するmake_sharedと、メモリ内にすべての場所が 1 つしかないため、新しい場所は 1 つだけになります。

これがGotW #89の目的であり、よく説明されているので、よく読んでください。

于 2012-04-25T10:26:11.767 に答える