C ++从字符串实例化类,从文件中读取

时间:2015-09-23 18:18:28

标签: c++

编辑:问题是我试图在我的cpp文件的全局范围内调用一个静态函数,由于某种原因它没有工作:

//Player.cpp
RTTI::instance()->registerClass(...) // ERROR
Player::Player() {}
Player::~Player() {}

为了解决这个问题,我改变了我的代码如下:

template <class T>
struct RTTIRegister {   
    RTTIRegister<T>(const std::string& name) { 
        RTTI::instance()->registerClass(name, &T::createInstance); 
    } 
};

#define PROTOTYPE_CREATE(CLASS, BASE) \     
    static BASE* createInstance() { return new CLASS(); }

#define PROTOTYPE_REGISTER(NAME, CLASS) \   
    RTTIRegister<CLASS> __rtti__(NAME);

&lt; ------------------- END OF EDIT -------------------- - &GT;

我正在尝试编写一个类/宏,这将使我能够创建类的实例,其名称我已经存储在字符串中,从文件中读取。我有很多类GameObject的派生类。当我使用下面的代码时,它在Visual Studio C ++ 2012 Express中给出了一个错误:

Error   2   IntelliSense: a trailing return type requires the 'auto' type specifier Player.cpp
Error   1   error C2061: syntax error : identifier 'registerClass'  player.cpp

为什么我收到此错误,我该怎么做才能解决?

代码:

// JSON 
{
    "GameObjects" : [
        {
            "Class" : "Player",
            "Health" : 15
        }
    ]
}

现在,当我的程序读取文件时,它应该创建一个Player类的实例。我目前拥有以下内容:

class RTTI
{
    typedef GameObject* (*createFunc)(void);

    public:
        static RTTI* instance();
        void registerClass(const std::string& className, createFunc instantiate);
        GameObject* createGameObject(const std::string& className);
    private:
        static RTTI* s_instance;
        std::map<std::string, createFunc> s_registeredClases;
};

#define PROTOTYPE_CREATE(CLASS) \
    static CLASS* createInstance() { return new CLASS(); }

#define PROTOTYPE_REGISTER(NAME, CLASS) \
    RTTI::instance()->registerClass(NAME, &CLASS::createInstance);

现在我的播放器类被定义为:

//Player.h
class Player : public GameObject
{
    PROTOTYPE_CREATE(Player)
}

//Player.cpp
PROTOTYPE_REGISTER("Player", Player) /* **THIS IS WHERE IT GIVES ME AN ERROR */
Player::Player() {}
Player::~Player() {}

在注册了一个类之后,我应该能够通过说RTTI :: createGameObject(&#34; Player&#34;);

来创建实例。

3 个答案:

答案 0 :(得分:0)

您尚未在类RTTI中定义静态instance()成员函数。但是你在宏中访问它:

#define PROTOTYPE_REGISTER(NAME, CLASS) \
RTTI::instance()->registerClass(NAME, &CLASS::createInstance);

PROTOTYPE_REGISTER也需要2个参数。

定义PROTOTYPE_CREATE(BASE,CLASS)\

static BASE* createInstance() { return new CLASS(); }
播放器类中的

将您的调用替换为PROTOTYPE_CREATE 同 PROTOTYPE_CREATE(GameObject,Player)

答案 1 :(得分:0)

您的一个障碍是创建功能的返回类型。大多数 factory 模式返回指向基类对象的指针,换句话说,返回单个返回类型。

工厂可以像一堆switch语句一样简单,使用 lookup 表。

查找表将包含一列中的键或字符串以及指向第二列中的创建函数的指针。在键列中搜索匹配的字符串,然后使用函数指针(在同一行中)创建该实例。同样,相同的障碍:创建函数必须在表中具有相同的签名(相同的返回类型)。

答案 2 :(得分:0)

try this: Very small difference from your code:

struct GameObject {

};
typedef GameObject* (*createFunc)(void);
class RTTI
{

public:
    static RTTI* instance();
    void registerClass(const std::string& className, createFunc instantiate);
    GameObject* createGameObject(const std::string& className);
private:
    static RTTI* s_instance;
    std::map<std::string, createFunc> s_registeredClases;
};

RTTI* RTTI::s_instance = nullptr;

RTTI* RTTI::instance()
{
    if (!s_instance)
    {
        s_instance = new RTTI();
    }
    return s_instance;
}
void RTTI::registerClass(const std::string& className, createFunc instantiate)
{
    s_registeredClases.insert(std::make_pair (className, instantiate));
}
GameObject* RTTI::createGameObject(const std::string& className)
{
    return nullptr;
}

**#define PROTOTYPE_CREATE(BASE, CLASS) \
    static BASE* createInstance() { return new CLASS(); }**

#define PROTOTYPE_REGISTER(NAME, CLASS) \
    RTTI::instance()->registerClass(NAME, CLASS::createInstance);


//Player.h
class Player : public GameObject
{
public:
    //static GameObject* createInstance() { return new Player(); }
    PROTOTYPE_CREATE(GameObject, Player);
};
//Player.cpp

int _tmain(int argc, _TCHAR* argv[])
{
    PROTOTYPE_REGISTER("Player", Player)
    return 0;
}