正如标题所示,我有一个与我的内联文件有关的链接器错误。它抱怨我的dungeon_layout标头包含我的dungeon_room标头(包括inl文件)定义了两次。我的所有标题都有警卫,我只包含.hpp文件,但当我尝试重载赋值运算符时它仍然生气。它抱怨的代码是这样的:
我需要分配1:
dungeon_room dungeon_layout::getCurrentRoom()
{
...
dungeon_room temp;
for (row = levelLayout.begin(); row != levelLayout.end(); row++)
{
for (col = row->begin(); col != row->end(); col++)
{
if (col->active)
{
...
temp = *col;
...
}
}
...
}
return temp;
}
我需要分配2:
dungeon_room::dungeon_room()
{
...
roomMap = tim::tileMap(20, 20, 50);
...
}
作业操作员1:
tileMap tim::tileMap::operator=(const tileMap& other)
{
// nothing...
}
作业操作员2:
void dungeon_room::operator=(const dungeon_room& other)
{
// nothing...
}
Tile Manager的标题(函数的inl文件定义)
#ifndef DUNGEON_ROOM_HPP
#define DUNGEON_ROOM_HPP
...
#include "gridManager\tileManager.hpp"
...
#endif
关卡布局的标题
#ifndef DUNGEON_LAYOUT_HPP
#define DUNGEON_LAYOUT_HPP
...
#include "dungeon_room.hpp"
...
#endif
错误:
1>dungeon_room.obj : error LNK2005: "private: void __cdecl
tim::tileMap::addSprite(class sf::RectangleShape,unsigned __int64)" (?addSprite@tileMap@tim@@AEAAXVRectangleShape@sf@@_K@Z) already defined in dungeon_layout.obj
1>dungeon_room.obj : error LNK2005: "private: void __cdecl tim::tileMap::addSprite(class sf::Sprite,unsigned __int64)" (?addSprite@tileMap@tim@@AEAAXVSprite@sf@@_K@Z) already defined in dungeon_layout.obj
1>dungeon_room.obj : error LNK2005: "public: void __cdecl tim::tileMap::modifyTile(int,int,int)" (?modifyTile@tileMap@tim@@QEAAXHHH@Z) already defined in dungeon_layout.obj
1>dungeon_room.obj : error LNK2005: "public: void __cdecl tim::tileMap::addCollisionValue(int)" (?addCollisionValue@tileMap@tim@@QEAAXH@Z) already defined in dungeon_layout.obj
1>dungeon_room.obj : error LNK2005: "public: void __cdecl tim::tileMap::drawTiles(class sf::RenderWindow &,class sf::View &)" (?drawTiles@tileMap@tim@@QEAAXAEAVRenderWindow@sf@@AEAVView@4@@Z) already defined in dungeon_layout.obj
1>dungeon_room.obj : error LNK2005: "public: void __cdecl tim::tileMap::drawTiles(class sf::RenderWindow *,class sf::View &)" (?drawTiles@tileMap@tim@@QEAAXPEAVRenderWindow@sf@@AEAVView@4@@Z) already defined in dungeon_layout.obj
1>dungeon_room.obj : error LNK2005: "public: void __cdecl tim::tileMap::drawTiles(class sf::RenderWindow &)" (?drawTiles@tileMap@tim@@QEAAXAEAVRenderWindow@sf@@@Z) already defined in dungeon_layout.obj
1>dungeon_room.obj : error LNK2005: "public: void __cdecl tim::tileMap::drawTiles(class sf::RenderWindow *)" (?drawTiles@tileMap@tim@@QEAAXPEAVRenderWindow@sf@@@Z) already defined in dungeon_layout.obj
1>dungeon_room.obj : error LNK2005: "public: void __cdecl tim::tileMap::operator=(class tim::tileMap const &)" (??4tileMap@tim@@QEAAXAEBV01@@Z) already defined in dungeon_layout.obj
1>dungeon_room.obj : error LNK2005: "public: __cdecl tim::tileMap::tileMap(void)" (??0tileMap@tim@@QEAA@XZ) already defined in dungeon_layout.obj
1>dungeon_room.obj : error LNK2005: "public: __cdecl tim::tileMap::tileMap(float,float,float)" (??0tileMap@tim@@QEAA@MMM@Z) already defined in dungeon_layout.obj
1>F:\Desktop Files\C++\Games\Dungeon_Seeker\x64\Debug\Dungeon_Seeker.exe : fatal error LNK1169: one or more multiply defined symbols found
我认为这应该是相关的代码。我已经卡住了,现在调试了一段时间,而且很烦人。请帮忙,谢谢!
答案 0 :(得分:1)
您收到这些错误的原因是因为正在为编译的每个.cpp文件编译该函数,然后对包含您的内联文件的每个.cpp文件进行多次导出。
包含该定义的.inl文件将粘贴到包含该文件的每个.cpp文件中。这意味着,当程序链接在一起时,有一个函数的定义,应该只在几个文件中定义一次。这打破了One Definition Rule,这就是链接器为您提供错误的原因。
要解决此问题,您有三种选择。首先,您可以将函数标记为inline
,这不一定使编译器内联函数,但允许多次定义函数。其次,您可以在类的定义中移动函数的定义,它隐式地将函数标记为内联。或者您可以在.cpp文件中定义该函数。
使用代码,如果您仍希望在.inl文件中声明函数,则可以在错误消息中将inline
放在函数定义的前面。在这种情况下,这些功能是
tim::tileMap::addSprite
tim::tileMap::modifyTile
tim::tileMap::addCollisionValue
tim::tileMap::drawTiles //All 4 overloads
tim::tileMap::operator=
tim::tileMap::tileMap //Both constructor overloads