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

C++ Instantiate class from string, read from a file

本文关键字:文件 读取 实例化 字符串      更新时间:2023-10-16

EDIT:问题是我试图在我的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 ;------------------- 编辑结束 ---------------------->

我试图写一个类/宏,这将使我能够创建类的实例,其名称我已经存储在字符串中,从文件读取。我有很多类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("Player");

创建实例

障碍之一是来自创建函数的返回类型。大多数工厂模式返回一个指向基类对象的指针,换句话说,只有一个返回类型。

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

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

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

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

PROTOTYPE_REGISTER也有2个参数

define PROTOTYPE_CREATE(BASE, CLASS)

static BASE* createInstance() { return new CLASS(); }
玩家类中的

替换你对PROTOTYPE_CREATE的调用与PROTOTYPE_CREATE (GameObject球员)

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;
}