Мои вопросы соответствуют ответу Йоханнеса в Есть ли способ создания экземпляров объектов из строки, содержащей их имя класса? и недавний комментарий от Спенсер Роуз. Поскольку я не могу добавить комментарий, я решил начать новый вопрос.
Мне нужно предложение Йоханнеса. Я реализовал это точно таким же образом, но у меня есть неразрешенная ошибка компоновщика внешних символов при использовании VS2008, которая, похоже, как-то связана с картой. Я пытаюсь со дня на день решить это. Сегодня я прочитал комментарий от Спенсера и добавил строку, которую он предлагает
BaseFactory::map_type BaseFactory::map = new map_type();
к Base.hpp. Теперь я получаю ошибку LNK2005
Derivedb.obj : error LNK2005:
"private: static class std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class Base * (__cdecl*)(void),struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class Base * (__cdecl*)(void)> > > * BaseFactory::map"
(?map@BaseFactory@@0PAV?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6APAVBase@@XZU?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6APAVBaser@@XZ@std@@@2@@std@@A)
already defined in Switcher.obj
Project.exe : fatal error LNK1169: one or more multiply defined symbols found)
вместо ошибки LNK2001
(Switcher.obj : error LNK2001: unresolved external symbol "private: static class std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class Base * (__cdecl*)(void),struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class Base * (__cdecl*)(void)> > > * BaseFactory::map" (?map@BaseFactory@@0PAV?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6APAVBase@@XZU?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6APAVBase@@XZ@std@@@2@@std@@A)
1>Derivedb.obj : error LNK2001: unresolved external symbol "private: static class std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class Base * (__cdecl*)(void),struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class Base * (__cdecl*)(void)> > > * BaseFactory::map" (?map@BaseFactory@@0PAV?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6APAVBase@@XZU?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6APAVBase@@XZ@std@@@2@@std@@A)
1>Project.exe : fatal error LNK1120: 1 unresolved externals)
что означает, что я мог определить это дважды?
Пожалуйста, могли бы Спенсер или кто-нибудь опубликовать улучшенный код base.hpp. Это настолько важное решение, что оно наверняка пригодится многим начинающим программистам на С ++.
Второй вопрос: -> Эта проблема решена! Спасибо!
Мне нужны объявления некоторых функций в base.hpp. Они должны были быть абстрактными в базовом классе и реализованы в подклассах (например, Derivedb.cpp). Но
public:
virtual ReadInFile(std::string path, std::string filename) = 0;
в base.hpp выдал ошибку компилятора. Удаление "= 0" решило ошибку компилятора. Но теперь у меня есть еще один неразрешенный внешний символ LNK2001 error
Derivedb.obj: error LNK2001: unresolved external symbol
"public: virtual __thiscall Base::ReadInFile(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)"
(?ReadInFile@Base@@UAE_NPAV@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@1@Z).
Я называю это в другом файле cpp
Base* importer = BaseFactory::createInstance("DerivedB");
importer->ReadInFile(m_path, m_filename);
Может быть, не ясно, какую функцию (базовый или подкласс) нужно вызывать, поскольку она не является абстрактной в базовом классе ??? Есть ли способ решить эту проблему? Спасибо!