4

次のようなモデル、メッシュなどを指す unique_ptrs のベクトルがあります。

std::vector<std::unique_ptr<Model>> mLoadedModels;

私が unique_ptr を選択したのは、ベクター デストラクタでデータが自動的に解放されるためです。また、後でたとえばすべてのモデルをリロードする必要がある場合 (OpenGL コンテキストの破棄/作成のため) は、リソース マネージャーで内部的に reset() を実行できるためです。新しい Model インスタンスを指すようにすると、システムの残りの部分には影響しません。

私の質問は、ベクターの内容を他のシステムとどのように共有しますか? unique_ptr を渡すだけでは所有権が変更されるため (unique_ptr が原因で)、rersource マネージャーに単独の所有権が必要です。

私が思いついた解決策は次のとおりです。次の構造体でアクセスをラップします。

template<typename T>
struct Handle
{
    Handle(std::unique_ptr<T>& resource) : mResource(resource)
    {
    }

    T& operator*()                  { return mResource.get(); }
    const T& operator*() const      { return mResource.get(); }
    T* operator->()                 { return mResource.get(); }
    const T* operator->() const     { return mResource.get(); }


private:
    std::unique_ptr<T>& mResource;
};

typedef Handle<Model> ModelPtr;

ModelPtr GetModel(const std::string& modelName);

// example:
ModelPtr monkey = GetModel("Monkey");
monkey->dance();

// reload resources, and then monkey dereferences to the new Model instance 

それは少しギミックな気がしますが、確かにこれに対するより良い、より簡単な解決策はありますか?

4

2 に答える 2

12

これには簡単な解決策があります。

受け渡しvec[n].get()-- 生のポインター。あなたがそれらを保管せず、常に所有者からそれらを取り戻し、あなたがそれらを使用している間に所有者がそれらを破壊しない限り、あなたは安全です.

そのレベルの規律に従う気がない場合、必要なのはstd::shared_ptr内の でありvector、 を回して保管する必要がありますstd::weak_ptr。s は、最後のものがweak_ptrなくなると自動的に無効になりshared_ptrます (ポリシーにより、唯一の永続的なshared_ptrものは所有するものvectorです)。

これには、要素で作業を行っている最中にvectorそれ自体をクリアしても、セグメンテーション違反が発生しないという追加の利点があります。weak_ptrbyにアクセスすると、 a.lock()が返されますshared_ptr。その有効期間中、生のポインターは正常であることが保証されます。

マイナス面は、コストが高くなることです。プラス面は、弱い共有所有権と無効化の遅延通知が可能になることです。

于 2013-07-19T18:59:26.483 に答える
0

プレーンstd::vector <Model>を使用して、個々の要素への生のポインターを渡します。動的ポリモーフィズムが必要な場合や、モデルへの参照がベクターよりも長生きすることが予想される場合を除き、これ以上複雑にする必要はありません。

于 2013-07-19T20:11:29.977 に答える