2013-02-22 2 views
0

Я пытаюсь создать систему класса автозагрузку, используя отображение класса, как указано в лучшем answere этого поста:C++ Compiler или Linker оптимизация

Is there a way to instantiate objects from a string holding their class name?

так я создал этот код на основе моих потребностей :

// 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); 

и, конечно, я определил REGISTER_DEC_TYPE в классе Foo и в нижней части foo.cpp файла я поместил: REGISTER_DEF_TYPE (Foo) ... (функция AddScripts вместо вызывается основной программой так он обычно связан в двоичных файлах)

он компилируется, но когда я пытаюсь отлаживать, я не могу установить точки останова в визуальной студии, которая показывает этот совет: «С этой линией не связан исполняемый код. Возможные причины включают в себя: директиву препроцессора или компилятор/линкер оптимизацию «

и foo.cpp он показывает:„любой символ был загружен для этого документа“

, так что я предполагаю, что компилятор не найти любой» нормальный "вызов этих функций/классы удаление их из двоичного кода.

есть ли способ, чтобы избежать такого рода оптимизации? я найти кроссплатформенное решение этой проблемы.

заранее спасибо

+1

Можете ли вы точно объяснить, какие строки в вашем коде вы устанавливаете точки останова? –

+0

любые строки функции RegisterCreator и createScript или везде в классе foo foo.cpp (вместо этого функция addScripts вызывается главным процессом, поэтому она обычно связана компилятором) – Joseph

+0

Вы уверены, что сможете ее скомпилировать? static 'ScriptReg reg' требует значения по умолчанию ctor, но есть только один, который принимает' std :: string const & s' –

ответ

2

D eadstripping - распространенная проблема с заводским кодом. То, что вам обычно нужно делать, - это функция, которая использует все ваши типы. Это уродливо, но, к сожалению, нет особо элегантных портативных решений.

+0

, так что требуется, чтобы все классы где-то в основном процессе регистрировались на карте? – Joseph

+0

Большинство компиляторов удаляют неиспользуемые символы (deadstripping), так что вы не получите неиспользуемого кряка в своем исполняемом файле. К сожалению, в этом случае, это слишком восторженное, да, вы должны использовать их. Это позволит сделать все ваши вызовы регистра в центральной функции 'register'. –