1

我有一个类,ResourceManifest它从文件中加载 3d 模型并将它们保存在向量中,然后按要求分发它们。也可以从存储中删除缓存的 3dmodel,我希望我的其他组件在发生这种情况时能意识到这一点。这是我现在拥有的,但它不能满足我对属于ResourceManifest该类的唯一所有权的意图

    typedef boost::shared_ptr<Model> ModelPtr;

    class ResourceManifest
    {
    public:
        ResourceManifest(IRenderer& renderer);
        ~ResourceManifest();

        ModelPtr LoadModel(const std::string& modelName, const std::string& assetName);
        ModelPtr GetModel(const std::string& modelName);
        void DeleteModel(ModelPtr model);


    private:
        IRenderer& mRenderer;
        std::vector<ModelPtr> mModels;
        IMemoryAllocator& mMemoryAllocator;
    };

在我的第一次尝试中,我将其保留Model为 shared_ptrs; 但结果是,正如暗示的那样,它是共享所有权,我只希望位于向量内的副本ResourceManifest成为所有者。我想要一个智能指针的原因只是为了能够查询它是否Model仍然存在,这是我不能用原始指针做的事情。

我知道weak_ptr,但如果可能的话,我宁愿避免使用它的语法;如果可能的话,我想像普通指针一样使用它,就像这样......

ModelPtr modelCube = resourceManifest.GetModel("Cube");

...... later on

if (modelCube)
    modelCube->render();
4

2 回答 2

1

解决您的问题的一种解决方案是使用weak_ptr,但据我了解您的问题,您不喜欢它的语法。ResourceManifest::GetModel 将返回一个weak_ptr,您必须使用 .lock() 才能将 shared_ptr 传递给模型,如果 .lock() 成功,则会产生一个您可以使用的有效 shared_ptr。

您在问题中没有提到的 shared_ptr/weak_ptr 方法的另一个问题是,ResourceManifest 不会真正成为模型的所有者,即使它只分发weak_ptr 之外的任何东西。我的意思是,没有什么可以阻止 ResourceManifest 的用户将weak_ptr 提升到shared_ptr 并保留shared_ptr,从而使其存活时间超过ResourceManifest 想要的时间。简而言之,ResourceManifest 失去了对模型生命周期的控制。

你可以做的是发明你自己的智能指针,它只保留原始指针:

MySmartPtr model = manifest.GetModel("foobar");

如果原始指针有效,则执行布尔测试:

if (model)

例如,您的智能指针可以询问 ResourceManifest 指针是否有效。如果指针有效,用户可以通过智能指针的取消引用运算符使用指针:

  model->render();

但是这里有一个问题:如果要从多个线程中使用您的智能指针和 ResourceManifest,您的

if (model)
  model->render();

成为竞争条件,但是由于您的问题没有提到多个线程,因此我不会为此提供答案...

于 2013-04-10T21:47:09.320 回答
1

您可以为weak_ptr. 这是一个简单的,未完成的,可以帮助您入门。

template<typename T>
class weak_ptr2
{
public:
    weak_ptr2(std::shared_ptr<T> const & sp)
        :wp(sp)
    {}

    T & operator*() const { return *(wp.lock()); }
    T * operator->() const { return wp.lock().get(); }
    explicit operator bool() const { return !wp.expired(); }
private:
    std::weak_ptr<T> wp;
};
于 2013-04-10T21:27:28.310 回答