Неразрешенный внешний символ?
Возможный дубликат:
Что такое неопределенная ссылка / неразрешенная внешняя ошибка символа и как ее исправить?
Я ужасно читаю ошибки C++, но очевидно, что Unresolved External Symbol означает, что функция, которую я использую, не определена. Я получаю ошибку...
1>WorldState.obj : error LNK2001: unresolved external symbol "public: class Brutal::GameObject * __thiscall Brutal::GameObjectManager::createObject<class Player>(class Ogre::Vector3,class Ogre::Quaternion,class Brutal::PropertyList,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??$createObject@VPlayer@@@GameObjectManager@Brutal@@QAEPAVGameObject@1@VVector3@Ogre@@VQuaternion@4@VPropertyList@1@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>C:\Users\Brett\Desktop\Factions Online\build\release\client\client.exe : fatal error LNK1120: 1 unresolved externals
Это не имеет никакого смысла, так как createObject определен и даже подходит в MSVC, когда я щелкаю его правой кнопкой мыши и нажимаю "перейти к определению"
Мой код, который называет это...
Brutal::GameObjectManager::getSingletonPtr()->createObject<Player>(Ogre::Vector3::ZERO, Ogre::Quaternion::IDENTITY);
Так я что-то упустил глупо?
4 ответа
Поскольку вы используете функцию шаблона, ее определение должно быть видно при вызове. Следовательно, поскольку это функция-член, она должна быть реализована в заголовке, в котором вы ее объявили.
Учитывая, что это шаблон, вы поместили реализацию в файл, отличный от заголовка? (Вы можете сделать это для определенных классов, для которых вы решили объявить, что у вас есть реализация шаблона, известная как создание экземпляра).
Я собираюсь расширить свой предыдущий пост, поскольку я могу добавить здесь предложения по кодированию легче, чем в комментарии.
У вас есть шаблонная функция с именем createObject. Вы можете подумать об "рефакторинге" этого, чтобы использовать класс, потому что это легче выделить.
Это пример кода, поэтому заполните детали, чтобы он работал именно для вашего примера.
class GamePlayerManager
{
public:
// all the other stuff
template< typename T > createObject(/*params */)
{
// implement inline
res = GameObjectFactory<T>::create(/* whatever parameters */);
}
};
Теперь я выделил создание объекта в свой собственный класс, называемый GameObjectFactory. В какой-то момент, когда Player виден, вы можете создать экземпляр этого шаблона, скрывая при этом его метод create().
template class GameObjectFactory<Player>;
Это достаточно для того, чтобы компилятор знал, что ему нужно искать в реализации функции этого класса (он превращает его в "настоящий" класс, чтобы вы могли поместить реализацию в его файл.cpp). Обратите внимание, что это экземпляр, а не специализация, поэтому ваш шаблон GameObjectFactory может по-прежнему реализовывать любые функции, которые вы хотите встроить, и вам не придется переопределять их для вашего класса. Это хороший способ "повторно" использовать общий код, позволяя вам специализироваться на некоторых деталях.
Похоже, вы не ссылаетесь на связанную библиотеку. У вас есть заголовок, поэтому компилятор не жалуется, но компоновщик не знает, о чем вы говорите.
CreateObject принимает аргументы по умолчанию или перегружен?
Если да, вы определяете все версии этой функции?
В сообщении об ошибке отображается больше параметров для функции, чем в вызове.
И если функции определены в какой-либо другой библиотеке, вы должны связать ее с вашим приложением, предоставив эту библиотеку в качестве входных данных для компоновщика в настройках проекта.