2017-04-23 17 views
0

リソースの所有者と所有者以外の2つのコンテナがあります。私は所有者が1人しかいないので、unique_ptrが必要だと思います。std :: unique_ptrの所有権のないコピー

class OwnershipContainer { 
public: 
    void add(std::unique_ptr<Obj> obj) { 
     objects.push_back(std::move(obj)); 
    } 
    Obj* get(std::size_t i) { return objects[i].get(); } 
private: 
    std::vector<std::unique_ptr<Obj>> objects; 
}; 

私は所有者以外のコンテナにどのようなポインタを使用する必要がありますか?最初の考えは生のポインタだった。しかし、Objの生存期間が非所有者コンテナの生涯と一致するか、それを超えることを保証することはできません。

class NonOwnershipContainer { 
public: 
    void add(Obj *obj) { 
     objects.push_back(obj); 
    } 
    Obj* get(std::size_t i) { return objects[i]; } 
private: 
    std::vector<Obj*> objects; 
}; 

int main() { 
    NonOwnershipContainer nonOwnershipContainer; 
    { 
     OwnershipContainer ownershipContainer; 
     ownershipContainer.add(std::make_unique<Obj>(1)); 

     nonOwnershipContainer.add(ownershipContainer.get(0)); 
    } 
    auto pobj = nonOwnershipContainer.get(0); // dangling pointer 
} 

私は非所有者の所有者とのweak_ptrのためのshared_ptrを使用することができ、そのweak_ptrを期限が切れたりされていない場合、私はチェックすることができます。しかし、shared_ptrは私が所有権を共有していることを意味します。私の場合はそうではありません。参照カウンタは必要ありません。

EDIT:

私は寿命を延長するつもりはありませんよ。所有者のコンテナが破壊されたとき、私はポインタがつかないようにしたい。上で書いたように、私はshared_ptr + weak_ptrを使うことができました。

class OwnershipContainer { 
public: 
    void add(std::shared_ptr<Obj> obj) { 
     objects.push_back(obj); 
    } 
    std::shared_ptr<Obj> get(std::size_t i) { return objects[i]; } 
private: 
    std::vector<std::shared_ptr<Obj>> objects; 
}; 


class NonOwnershipContainer { 
public: 
    void add(std::shared_ptr<Obj> obj) { 
     objects.push_back(obj); 
    } 
    std::shared_ptr<Obj> get(std::size_t i) { return objects[i].lock(); } 
private: 
    std::vector<std::weak_ptr<Obj>> objects; 
}; 

int main() { 
    NonOwnershipContainer nonOwnershipContainer; 
    { 
     OwnershipContainer ownershipContainer; 
     ownershipContainer.add(std::make_shared<Obj>(1)); 

     nonOwnershipContainer.add(ownershipContainer.get(0)); 
    } 
    auto pobj = nonOwnershipContainer.get(0); // no more dangling pointer, pobj == nullptr 
} 

しかし、この場合には、私は参照カウンタを支払う、それは哲学的に間違っている:唯一の所有者の利用のshared_ptrと。

+0

普通の 'std :: vector 'に対する引数は何ですか?あなたはメインの外見でやっていることは非常に危険です。本質的にあなたは寿命を延ばそうとしています。つまり所有権が間違っています。 – stefan

+0

私は継承と多相を使用しています。Objは基本クラスです。 –

+1

所有コンテナが唯一の所有者であると想定されている場合、オブジェクトへのアクセスはすべてそれを通過しなければなりません。 – StoryTeller

答えて

2

あなたが実際には、所有権を共有しています:あなたはNonOwningContainer -containedポインタのようなものを経由してオブジェクトにアクセスするときは、所有権を取得しなければならない、またはあなたはそれで作業している間、オブジェクトがあなたの下から消えることがあります。

あなたは、オブジェクトがあなたの下から消えていないことを保証することはできませんので:

をしかし、私は非所有者のコンテナの寿命を保証を与えることはOBJ試合の寿命または超えることはできません。

あなたの唯一の選択肢は、所有権を共有することです。したがって、shared_ptrweak_ptrが適切なアプローチです。

また、OwnershipContainerNonOwnershipContainerの寿命の違いによっては、the interaction between std::make_shared and std::weak_ptrに注意してください。

関連する問題