1

可能重复:
什么是未定义的引用/未解决的外部符号错误,我该如何解决?

我在阅读 c++ 错误方面很糟糕,但显然未解析的外部符号意味着我正在使用的函数没有定义。我得到的错误是......

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

4 回答 4

2

由于您使用的是模板函数,因此在调用它时它的定义必须是可见的。因此,因为这是一个成员函数,它必须在你声明它的头文件中实现。

于 2010-10-21T15:02:03.530 回答
1

鉴于它是一个模板,您是否将实现放在与标头不同的文件中?(您可以为您决定声明您具有模板实现的特定类执行此操作,称为实例化)。

我将扩展我之前的帖子,因为我可以在这里比在评论中更容易地提出编码建议。

您有一个名为 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 仍然可以实现您想要内联的任何函数,并且您不必为您的类重新定义它们。这是“重用”通用代码的好方法,同时允许您专注于某些细节。

于 2010-10-21T14:41:25.560 回答
0

看起来您没有链接到关联的库。你已经包含了头文件,所以编译器没有抱怨,但链接器不知道你在说什么。

于 2010-10-21T14:33:12.277 回答
0

createObject 是采用默认参数还是重载?

如果是这样,您是否定义了该功能的所有版本?

在错误消息中,它显示的函数参数多于调用中的参数。

如果函数是在其他库中定义的,则必须通过将该库作为项目设置中的链接器的输入将该库与您的应用程序链接。

于 2010-10-21T14:36:19.990 回答