0

我正在尝试使用本文最佳答案中指定的类映射创建一个自动加载类系统:

有没有办法从保存类名的字符串中实例化对象?

所以我根据我的需要创建了这个代码:

// ScriptLoader.h
template<class TScript> void createScript() { 
    new TScript; 
}

struct ScriptFactory {
public:
    typedef void(*ScriptCreatorFunc)();
    typedef std::map<std::string,ScriptCreatorFunc> ScriptCreatorStorage;

    static ScriptCreatorStorage ScriptCreators;

    static bool RegisterCreator(std::string const& s,ScriptCreatorFunc creator)
    {
        ASSERT(ScriptCreators.find(s) == ScriptCreators.end());   // prevent registering the same script twice
        ScriptCreators.insert(std::make_pair(s,creator));
        return true;
    }
};

template<class TScript>
struct ScriptReg : ScriptFactory { 
    ScriptReg(std::string const& s) { 
        ScriptFactory::RegisterCreator(s,&createScript<TScript>);
    }
};

class ScriptLoader {
public:
    static void AddScripts()
    {
        for (ScriptFactory::ScriptCreatorStorage::iterator itr = ScriptFactory::ScriptCreators.begin(); itr != ScriptFactory::ScriptCreators.end(); ++itr)
            itr->second();
    }    
};

#define REGISTER_DEC_TYPE(NAME) \
    static ScriptReg<NAME> reg

#define REGISTER_DEF_TYPE(NAME) \
    ScriptReg<NAME> NAME::reg(#NAME)


// ScriptLoader.cpp
ScriptFactory::ScriptCreatorStorage ScriptFactory::ScriptCreators;

// foo.cpp
class foo:
{
    public:

        foo()
        {
                /* code */
        }

    private:
        REGISTER_DEC_TYPE(foo);
};

REGISTER_DEF_TYPE(foo);

当然,我已经在 foo 类中定义了 REGISTER_DEC_TYPE,并且在 foo.cpp 文件的底部我放了: REGISTER_DEF_TYPE(foo) ...( AddScripts 函数改为由主程序调用,因此它通常在二进制文件中链接)

它编译得很好,但是当我尝试调试时,我无法在显示此提示的 Visual Studio 中设置断点:“没有可执行代码与此行关联。可能的原因包括:预处理器指令或编译器/链接器优化”

并在 foo.cpp 中显示:“已为此文档加载任何符号”

所以我猜编译器没有找到对这些函数/类的任何“正常”调用,将它们从二进制代码中删除。

有什么办法可以避免这种优化?我正在寻找解决此问题的跨平台解决方案。

提前致谢

4

1 回答 1

2

死区剥离是工厂代码的常见问题。您通常需要做的是在某处有一个使用您所有类型的函数。这很丑,但不幸的是没有特别优雅的便携式解决方案。

于 2013-02-22T13:52:52.097 回答