I'm trying to create an autoload class system using class mapping as specified in best answere of this post:
Is there a way to instantiate objects from a string holding their class name?
so i've created this code based on my needs:
// 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);
and of course i've defined REGISTER_DEC_TYPE in a foo class and at bottom of foo.cpp file i've put: REGISTER_DEF_TYPE(foo) ... ( AddScripts function instead is called by main program so it's normally linked in binaries )
it compiles well but when i try to debug , i cannot set breakpoints in visual studio that shows this tip: "No executable code is associated with this line. Possible causes include: preprocessor directive or compiler/linker optimization"
and in foo.cpp it shows: "any symbol has been loaded for this document"
so i guess the compiler don't find any "normal" call to these functions/classes removing them from the binary code.
Is there any way to avoid this kind of optimization? i'm finding a crossplatform solution to this problem.
thanks in advance
Deadstripping is a common problem with factory code. What you usually have to do is have a function somewhere that uses all of your types. It's ugly but unfortunately there are no particularly elegant portable solutions.