2017-05-17 5 views
2

私は時代とともに移動しており、自分自身を使ってスマートポインタに自分自身を公開するという目的で新しいプロジェクトを開始するべきだと思った。私はunique_ptrの大きなプールに衝突コンポーネントを格納することを考えています。これらのコンポーネントは、const refによって、ptrs上で読み取り専用のopsを内部的に実行するクワッドツリーに渡されます。
私は実装の意図を反映するための簡単な例を書いています。複数のインスタンスがunique_ptrへの参照を保持

struct Owner 
{ 
    unique_ptr<int> uPtr; 
}; 

struct SomeContainer 
{ 
    list<const unique_ptr<int>*> uPtrList; 

    void Insert(const unique_ptr<int>& borrowedUPtr) 
    { 
     list.push_back(&borrowedUPtr); 
    } 

    void DoSomething() 
    { 
     for(const auto& ptr : uPtrList) 
      // Perform read ops 
    } 
}; 

これらは私の意図している: Ownerunique_ptrを所有し、それによってその寿命を制御します。 SomeContainerは、ポインターへのconst参照を格納しません。これは、ポインターのリセットも変更も許可されていないためです。
これは実行可能なアプローチですか、私は力を乱していますか?

+2

この時点で 'list 'を使用することもできます。 'unique_ptr'の状態が実際に指しているオブジェクトよりももっと興味を持っていない限り、そうではありません。 –

+1

私には、所有者は 'std :: shared_ptr'を持っていて、' SomeContainer'はそれらの 'shared_ptr'に対して' std :: weak_ptr'を保持する必要があります。私はあなたがそれらを 'const'にすることができるかどうか分かりません。 – NathanOliver

+1

あなたのリストにはunique_ptrsへのポインタが含まれています...私はそれが理にかなっているとは思わない。 unique_ptrは所有権に関するものです。 SomeContainerが所有していない場合は、代わりにconst *を使い、unique_ptrは使用しないでください。 SomeContainerが元の所有者と所有権を共有するようにしたい場合は、shared_ptrの使用をよくしてください。 – AlexG

答えて

3

2つの解決策があります。

そのうちの一つは、あなたの所有者がstd::shared_ptrを持っているということとSomeContainerstd::weak_ptrのリストを維持し、このようなものでした:

struct Owner 
{ 
    std::shared_ptr<int> uPtr; 
}; 

struct SomeContainer 
{ 
    list<std::weak_ptr<int>> uPtrList; 

    void Insert(std::shared_ptr<int> borrowedUPtr) 
    { 
     list.push_back(std::weak_ptr<int>(borrowedUPtr)); 
    } 
    //... 
}; 

もう一つはSomeContainerstd::unique_ptr::getを経て得られたconstの生のポインタのリストを維持しているかもしれません。所有者が所有権を持っているため、OwnerSomeContainerより長くか長く存続することが保証できる場合、そのような戦略に間違いはありません。 Personnaly、私はこの1つを好む:

struct Owner 
{ 
    unique_ptr<int> uPtr; 
}; 

struct SomeContainer 
{ 
    list<const int*> uPtrList; 

    //Could also be directly passed as a const int* 
    void Insert(const unique_ptr<int>& borrowedUPtr) 
    { 
     list.push_back(borrwedUPtr.get()); 
    } 
    //... 
}; 
+0

2番目のケースでは、 'int'を' unique_ptr'を使って所有するのはどうしてなぜだけではないのですか? –

+3

最初の例では、 'Insert'は入力として' shared_ptr'を取ってから、それからそれ自身の 'weak_ptr'を構築する必要があります。' void Insert(std :: shared_ptr borrowedUPtr){list.push_back(std :: weak_ptr (借用UPtr)); } ' –

+0

@RemyLebeauあなたが正しいです。これを指摘してくれてありがとう、私はそれを変更 – Rosme

2

ここでは、スマートポインタを使う必要がある理由は明らかではありません。シンプルなメンバ変数がうまく所有権を表現する:

struct Owner 
{ 
    int value; 
}; 

そしてオブザーバーは、生のポインタを格納することができます:

struct SomeContainer 
{ 
    list<const int*> ptrList; 

    void Insert(const int& borrowedValue) 
    { 
     ptrList.push_back(&borrowedValue); 
    } 

    void DoSomething() 
    { 
     for(const auto& ptr : ptrList) 
      // Perform read ops 
    } 
}; 

これは、あなたがオブザーバーがしたい一方で、所有者が生き続けることを確信することができ想定しています観察する。あなたがそれを確信できないなら、unique_ptrはあなたを助けず、weak_ptrshared_ptrのような何かが必要になります。

+0

私はスマートポインターにもっと夢中になりたいと思いました。おそらく、それは ''の代わりに 'int'を使うのは悪い選択でしたが、これはSOのために非常に簡略化されました。これはコンパイル時に型が知られていないのでポインタにする必要があります。別の答えですが、私はあなたに健全な代替ソリューションを提供し、全体としての議論に貢献するために+1を与えます。 – SvinSimpe

関連する問題