2016-07-09 15 views
4

私が知っているクラスはです。は常にstd::shared_ptrになります。しかし、shared_ptrまたはweak_ptrを所有権や生涯保証を必要としない関数やメソッドに渡すと、不必要なオーバーヘッドが発生します。これを回避するために、関数への生ポインタを渡すことがよくあります。クラス自体はstd::enable_shared_from_thisから継承されます。したがって、関数がポインタの所有権を必要とする場合は、クラスのメソッドを使用してshared_ptrを取得できます。shared_from_thisに相当するweak_ptrはありますか?

これはすべて美しく動作しています。しかし、実際に生ポインタからshared_ptrを作成したくない場合がありますが、代わりに私が欲しいのはweak_ptrです。

私はstd::shared_ptrの通常の実装について理解しているので、参照カウンタとして使用される2つの原子変数があります。 1つはshared_ptr、1つはweak_ptrです。

私が持っているのは私のクラスへの生ポインタで、weak_ptrが必要な場合は、まずshared_ptrを作成して変換する必要があります。コピーshared_ptrカウンタ をデクリメント、shared_ptrがスコープの外に出ることを許可weak_ptrカウンタ

  • をインクリメントし、weak_ptrを構築shared_ptrカウンタ
  • をインクリメントし、shared_ptrを構築

    • :そうすることで、参照カウンタは、次のように変更されることを意味します

      これは「あなたが使用していないものを支払うことはない」という考え方に反しているようです。私のクラスが最初にshared_ptrを作成せずにweak_ptrを提供する方法はありますか?

  • +0

    「enable_shared_from_this」よりも「shared_from_this」に相当するものが必要です。 'weak_from_this'のようなもの。 –

    +1

    あなたは正しいです、私はタイトルを編集します。 C++のために 'weak_from_this'が提案されましたが、私は今使っているものを探しています。 – Fibbles

    +0

    これは 'std :: make_shared ()'を使ってクラスが作成されたことを意味します。それらは、生のポインタを渡すスコープよりもずっと前になります。生ポインタが渡されたスコープを越えて格納される必要がある場合、それは 'shared_ptr'に変換されます。 – Fibbles

    答えて

    5

    それがライブラリに置く価値はないことを実現することはほぼので、些細なのですが、私のクラスはちょうど最初のshared_ptrを作成せずのweak_ptrを提供するための方法はありますか?

    いいえ。 enable_shared_from_thisがサポートする唯一の操作はshared_ptrです。今、enable_shared_from_thisweak_ptrを直接構築するのに十分な情報を持っているはずです。クラスは実装の詳細をあなたに公開しないので、外部からはできません。

    Kerrekが指摘しているように、C++ 17はenable_shared_from_thisクラスからweak_ptrをフェッチする必要があります。

    +0

    C++ 14に関する限り正解であるので、私はこれを受け入れています。私はいくつかの教祖が独創的な回避策を掲示することを望んでいたが、そうは思わない。 – Fibbles

    3

    それは...

    #include <memory> 
    
    template<class T> std::weak_ptr<T> weak_from_this(T*p) { 
        return { p->shared_from_this() }; 
    } 
    
    struct S : std::enable_shared_from_this<S> 
    { 
        auto foo() { 
        return weak_from_this(this); 
        } 
    }; 
    
    
    int main() 
    { 
        auto ps = std::make_shared<S>(); 
        auto wps = ps->foo(); 
    } 
    
    +1

    ここにnoobishnessを表示しようとしていますが、ここでshared_ptrの構築を妨げるRVOですか?それ以外の場合、原子参照カウンタは依然としてインクリメントされます。 – Fibbles

    +0

    私はOPが既存の変換を認識していると思います。中間参照カウントのバンプを避けることが目的でした。 –

    +0

    @KerrekSBは私が参照してください。いいえ、標準よりも前にこのようなweak_ptrが存在することさえ示していないため、C++の前にバンプを避ける方法はありません。 –

    7

    提案P0033は、std::enable_shared_from_thisに由来するクラスにweak_from_thisを追加する、2015年10月の会議でC++ 17として承認されました。

    関連する問題