C ++ LNK2005在内联文件中

时间:2015-05-20 17:44:00

标签: c++11

正如标题所示,我有一个与我的内联文件有关的链接器错误。它抱怨我的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

我认为这应该是相关的代码。我已经卡住了,现在调试了一段时间,而且很烦人。请帮忙,谢谢!

1 个答案:

答案 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