Trouble with #include, C++

Trouble with #include, C++

本文关键字:C++ #include with Trouble      更新时间:2023-10-16

我知道这是一个常见的问题,但我很确定我包含文件的方式没有错误。

我给你基本文件。

Main.cpp:

#include "GameState.h"
#inlcude "Timer.h"
int main ( int argc, char** argv ) {

GameState.h:

#pragma once
#include "Character.h"

Character.h:

#pragma once
#include "Setup.h"

Setup.h:

#pragma once
#include "SDL.h"
#include "SDL_main.h"
#include "SDL_image.h"

错误报告:

Error   1   error LNK2005: "void __cdecl apply_surface(int,int,struct SDL_Surface *,struct SDL_Surface *,struct SDL_Rect *)" (?apply_surface@@YAXHHPAUSDL_Surface@@0PAUSDL_Rect@@@Z) already defined in Character.obj   C:UsersJimDocumentsC++herorpgherorpgMain.obj
Error   2   error LNK2005: "bool __cdecl init(struct SDL_Surface * &)" (?init@@YA_NAAPAUSDL_Surface@@@Z) already defined in Character.obj   C:UsersJimDocumentsC++herorpgherorpgMain.obj
Error   3   error LNK2005: "bool __cdecl load_files(struct SDL_Surface * * const)" (?load_files@@YA_NQAPAUSDL_Surface@@@Z) already defined in Character.obj C:UsersJimDocumentsC++herorpgherorpgMain.obj
Error   4   error LNK2005: "struct SDL_Surface * __cdecl load_image(char *)" (?load_image@@YAPAUSDL_Surface@@PAD@Z) already defined in Character.obj    C:UsersJimDocumentsC++herorpgherorpgMain.obj
Error   6   error LNK1169: one or more multiply defined symbols found   C:UsersJimDocumentsC++herorpgDebugherorpg.exe

我写的有什么问题吗?如果你认为需要更多的信息,我将张贴完整的代码。以前好像很讨厌。

c++有一个叫做单定义规则的规则。除其他事项外,该规则规定在整个程序中不能有多个函数定义。你不能有两个翻译单元都定义了一个函数,否则你就违反了这个规则。你可以把一个翻译单元想象成一个.cpp文件,它的所有头文件都包含在适当的位置。

如果你有一个头文件,foo.h,它看起来像这样:

#ifndef FOO_H
#define FOO_H
int foo() { return 5; }
#endif

然后你把这个头文件包含在两个或更多的.cpp文件中,每个翻译单元都有自己的定义。这违反了一个定义规则。

要解决这个问题,你的头应该给出一个函数声明,像这样:

#ifndef FOO_H
#define FOO_H
int foo();
#endif

然后在相应的foo.cpp文件中给出函数的定义:

#include "foo.h"
int foo() { return 5; }

这意味着只有foo.cpp翻译单元才有foo的定义。foo在其他翻译单元中的任何使用都将链接到到该定义。

另一种方法是将函数声明为inline,如:
#ifndef FOO_H
#define FOO_H
inline int foo() { return 5; }
#endif

允许这样做的原因是,每次翻译必须能够看到这样一个函数的定义,以便能够内联它。但是,我不建议无论是否愿意都使用inline

链接器错误不是由#include错误引起的。当编译器找不到某些东西的定义时,通常会发生链接器错误。或者如果它找到多个定义(如在本例中)

检查您是否与多个SDL库链接,或者您是否在代码的某个地方自己定义了函数

可能原因:

  1. 定义头文件中的函数。函数只能在。cpp文件中定义

  2. 循环头文件,包括。比如:a.h包括b.h, b.h包括c.h, c.h包括a.h。有时循环的包括并不明显,但它确实发生了。"#pragma once"只能防止一个头文件被多次包含,但不能防止循环包含。为了解决这个问题,使用"前向声明"来代替一些#include语句。

关于前向声明的链接:

http://en.wikipedia.org/wiki/Forward_declaration

什么时候可以使用前向声明?

http://msdn.microsoft.com/en-us/library/f432x8c6 (v = vs.80) . aspx