2

这个问题可能很难理解,但问题很简单,我将在这里用简单的语言来描述它。现在,我的资源管理是:

    cResMgr<cTexture> textures;
    cResMgr<cSound> sounds;

我想做的是:

    cResMgr resources;
    resources.add<cTexture>(...);
    resources.get<cSound>(...);

基本上,我的资源管理器具有“获取”和“添加”功能。我希望当我第一次调用 cWhatever 类型的函数时,它会为它创建一个容器。下次调用时,它就在那里(类似于函数中的静态变量)

问题是,我该如何实现它?我能想到的唯一解决方案是让每个资源都派生自空基类 cResource,这样我就可以拥有一个指向 cResource 的指针容器。问题是,资源类型不是我的(它们来自外部库)

有什么解决办法吗?

4

3 回答 3

2

我真的不知道你为什么不只是为每种资源类型使用不同的资源管理器。

此外,如果集合可以是全局静态的,为什么需要资源管理器的实例?

无论如何,这应该做你所描述的:

#include <string>
#include <map>

typedef double cTexture;
typedef std::string cSound;

struct cResMgr
{
    template <typename T>
        void add(std::string const& id, T const& v) const
        {
            mapFor<T>()[id] = v;
        }

    template <typename T>
        T& get(std::string const& id) const
        {
            return mapFor<T>().at(id);
        }

    private:
    template <typename T>
    static std::map<std::string, T> mapFor()
    {
        static std::map<std::string, T> _theMap;
        return _theMap;
    }
};

int main()
{
    cResMgr resources;
    resources.add<cTexture>("wall", cTexture {});
    resources.get<cSound>("sad_trombone");
}
于 2013-02-08T22:02:17.560 回答
1

你在正确的轨道上使用了一个用于类型擦除目的的基类,并让你的资源管理器持有指向它的资源的指针。就像您暗示的那样,让资源系统的用户从基类中获取资源是不合理的负担。

所以,你需要做的是创建一个类来包装资源......

class ResourceBase
{
    /*...*/
};

template<typename T>
class Resource : public ResourceBase
{
    /* contains a T. T is the user's resource */
};

然后,您的资源管理器可以包含 ResourceBase 指针列表。当用户说resources.get<cSound>("sound7");您可以查找ResourceBase指针(如果有)时,将其向下转换为 aResource<cSound>并返回cSound包含的指针。

于 2013-02-08T22:03:02.637 回答
1

您可以使用地图。当然,这是在运行时解决的,这有点违背模板在编译时尽可能多地解决的目标。此外,容器会有点棘手,因为容器没有一些抽象基类。我会为此使用 Boost.Any。然后看起来像这样:

template<res_type>
container<res_type>& get()
{
     map<type_info, boost::any>::iterator it = map.find(typeid(res_type));
     if(it == map.end())
         map[typeid(res_type)] = container<res_type>();
     boost::any& c = map[typeid(res_type)];
     return boost::any_cast<container<res_type> >(c);
}

我没有编译这个,但我希望它能够理解这一点。最后,一个问题:你真的有这么多不同的类型,所有这些都值得麻烦还是好奇。

于 2013-02-08T22:05:38.123 回答