この投稿の最良の回答で指定されているクラス マッピングを使用して、自動ロード クラス システムを作成しようとしています。
クラス名を保持する文字列からオブジェクトをインスタンス化する方法はありますか?
だから私は自分のニーズに基づいてこのコードを作成しました:
// 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 関数がメインプログラムによって呼び出されるため、通常はバイナリでリンクされます)
コンパイルはうまくいきますが、デバッグしようとすると、次のヒントを示すビジュアル スタジオでブレークポイントを設定できません。
そして foo.cpp では、「このドキュメントに対して任意のシンボルがロードされました」と表示されます
したがって、コンパイラーは、これらの関数/クラスへの「通常の」呼び出しを見つけず、バイナリコードからそれらを削除していると思います。
この種の最適化を回避する方法はありますか? この問題に対するクロスプラットフォームのソリューションを見つけています。
前もって感謝します