如何修复工厂模式以消除这些编译错误?

发布于 2024-10-04 07:09:07 字数 2118 浏览 2 评论 0原文

我的目标是创建一个系统,其中我可以在运行时提供类的字符串名称,并让它依次返回该类的实例。 在搜索 stackoverflow 时,我发现了一个示例,它似乎完全符合我想要完成的任务,尽管我目前无法正确编译它。以下内容基于该代码:

//LevelObject.h    
#pragma once

#include <map>
#include <string>

class LevelObject
{
    protected:
        int ID;

    public:
        template<class T> static LevelObject* createT(void)
        {
            return new T(0);
        }

        LevelObject(void);
        ~LevelObject(void);
};

struct BaseFactory
{
    typedef std::map<std::string, LevelObject*(*)()> map_type;

    static LevelObject* createInstance(const std::string& s)
    {
        map_type::iterator it = getMap()->find(s);
        if(it == getMap()->end())
        {
            return 0;
        }
        return it->second();
    }

    private:
        static map_type* objectMap;

    protected:
        static map_type* getMap()
        {
            if(!objectMap)
            {
                objectMap= new map_type;
            } 
            return objectMap; 
        }
};

template<class T>
struct DerivedRegister : BaseFactory
{ 
    DerivedRegister(const std::string& s)
    { 
        getMap()->insert(std::make_pair( s, &LevelObject::createT<T> ));
    }
};


//Item.h
#pragma once

#include "LevelObject.h"

class Item :
    public LevelObject
{
    int ID;
    static DerivedRegister<Item> reg;

public:
    Item(int id);
    ~Item(void);
};


//Item.cpp
#include "Item.h"

Item::Item(int id)
{
    ID = id;
}

Item::~Item(void)
{
}

DerivedRegister<Item> Item::reg("item");

逻辑是派生对象(即 Item)将注册一个字符串并引用一个返回其自身实例的函数。在调用 createInstance 时,它​​将接收用户输入的字符串并使用映射来确定要返回的对象。

不幸的是,这段代码无法正确编译,并给出以下错误:

错误 1 ​​错误 C2752: 'std::tr1::_Remove_reference<_Ty>' : 不止一项部分专业化 匹配模板参数列表

错误 2 错误 C2528:“抽象” 声明符':指向引用的指针是 非法 c:\program files\microsoft 视觉工作室 10.0\vc\include\type_traits 965

错误 3 错误 C2528:“类型”:指针 引用是非法的 c:\program 文件\微软视觉工作室 10.0\vc\include\type_traits 349

如果有人可以帮助消除这些错误,我将不胜感激。 或者也许我一开始就完全错了,所以如果有人觉得我应该完全朝着不同的方向前进,请告诉我。

提前致谢。

My goal is to create a system wherein I can provide the string name of an class at run time and have it return an instance of that class in turn.
Searching stackoverflow, I came across an example that seems to do exactly what I am trying to accomplish, although I am currently unable to have it compile properly. The following is based on that code:

//LevelObject.h    
#pragma once

#include <map>
#include <string>

class LevelObject
{
    protected:
        int ID;

    public:
        template<class T> static LevelObject* createT(void)
        {
            return new T(0);
        }

        LevelObject(void);
        ~LevelObject(void);
};

struct BaseFactory
{
    typedef std::map<std::string, LevelObject*(*)()> map_type;

    static LevelObject* createInstance(const std::string& s)
    {
        map_type::iterator it = getMap()->find(s);
        if(it == getMap()->end())
        {
            return 0;
        }
        return it->second();
    }

    private:
        static map_type* objectMap;

    protected:
        static map_type* getMap()
        {
            if(!objectMap)
            {
                objectMap= new map_type;
            } 
            return objectMap; 
        }
};

template<class T>
struct DerivedRegister : BaseFactory
{ 
    DerivedRegister(const std::string& s)
    { 
        getMap()->insert(std::make_pair( s, &LevelObject::createT<T> ));
    }
};


//Item.h
#pragma once

#include "LevelObject.h"

class Item :
    public LevelObject
{
    int ID;
    static DerivedRegister<Item> reg;

public:
    Item(int id);
    ~Item(void);
};


//Item.cpp
#include "Item.h"

Item::Item(int id)
{
    ID = id;
}

Item::~Item(void)
{
}

DerivedRegister<Item> Item::reg("item");

The logic is that the derived objects, i.e. Item, will register a string and reference to a function that returns an instance of itself. On calling createInstance, it will take in a user inputted string and use the map to determine the object to return.

Unfortunately, this code is not compiling correctly, and gives me the following errors:

Error 1 error C2752:
'std::tr1::_Remove_reference<_Ty>' :
more than one partial specialization
matches the template argument list

Error 2 error C2528: 'abstract
declarator' : pointer to reference is
illegal c:\program files\microsoft
visual studio
10.0\vc\include\type_traits 965

Error 3 error C2528: 'type' : pointer
to reference is illegal c:\program
files\microsoft visual studio
10.0\vc\include\type_traits 349

If someone can help smooth out these errors, I would greatly appreciate it.
Or perhaps I am going about this entirely wrong in the first place, so if someone instead feels that I should be going in a different direction entirely please let me know.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜无邪 2024-10-11 07:09:07

这个问题已经发布很长时间了,但由于没有答案,而且我也在这里偶然发现,我想我应该添加一个。我复制了与您相同的工厂代码(来自 StackOverflow 答案 这里)并遇到了同样的问题。我在 这个 StackOverflow 答案。

事实证明,Visual Studio 2010(我假设您正在使用它)在 std::make_pair 方面存在问题。只需使用 std::pair 即可。至少这为我解决了同样的问题。

It's been a long time since this question was posted, but since there's no answer and I stumbled here too, I figured I'd add one. I copied the same factory code you did (from the StackOverflow answer here) and had the same problem. I found the solution at this StackOverflow answer.

It turns out Visual Studio 2010 (which I'm assuming you're using) has a problem with std::make_pair. Just use std::pair<std::string,LevelObject*(*)()> instead and you'll be good to go. At least that resolved this exact same problem for me.

撩心不撩汉 2024-10-11 07:09:07

我在 LevelObject 类构造函数和析构函数中添加了空主体:

LevelObject(void) { }
~LevelObject(void) { }

然后声明了 BaeFactory 类的静态 map 成员变量:

BaseFactory::map_type* BaseFactory::map;

并且编译的代码没有GCC 和 Visual Studio 中均出现错误。

I added empty bodies to the LevelObject class constructor and destructor:

LevelObject(void) { }
~LevelObject(void) { }

Then declared the static map member variable of the BaeFactory class:

BaseFactory::map_type* BaseFactory::map;

and the code compiled without errors in both GCC and Visual Studio.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文