繁体   English   中英

多个定义的符号 C++ 错误

[英]Multiple Defined Symbols C++ error

我认为ifndef something #define something body #endif解决了这个错误,所以我不确定为什么会这样。

//Library.h
#ifndef __LIBRARY__
#define __LIBRARY__

#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <cstdarg>
#include <vector>
#include <ctime>
#include <cmath>
#include <cstdlib>

//file includes
#include "Globals.h"

using namespace std;

#endif //__LIBRARY__

——

//globals.h
//global variables
#ifndef __GLOBAL__
#define __GLOBAL__

#include <vector>
#include <iostream>
#include <string>

//prototypes
bool Poglathon(std::vector<std::string>& text);
void NPCTalk(std::string const& speaker,std::vector<std::string> const& text);
void wait(double seconds);

//player stats
std::string name;
double str;     //strength
double wis;     //wisdom
double ref;     //reflex
double hp;      //health points
double i;       //initiative
double inte;    //intelligence
double c;       //courage
int gold;       //gold
int xp;         //experience
int ap;         //armour points
int wd;         //weapon damage
int lvl;        //level
int sp;         //skill points

#endif //__GLOBAL__

然后还有另外两个包含“Library.h”的cpp文件。

问题在于,在 globals.h 头文件中,您声明了一组默认具有外部链接的变量:即所有全局变量!

当您在头文件中创建函数原型时,您是在声明一个函数,而不是定义它。 对同一个函数有多个声明是完全合法的,这就是为什么如果几个不同的文件都#include相同的头并声明相同的函数,那就完全没问题了。 另一方面,如果头文件中有全局变量,那么您就是在定义这些变量。 变量在 C++ 中只能定义一次(这称为一个定义规则),如果多个文件定义了相同的变量或函数,则会导致链接器错误,因为链接器不知道要使用哪个版本。 顺便说一下,这就是您没有#include .cpp 文件的原因,因为如果您这样做了,您将多次定义该标头导出的所有函数。

要解决此问题,您需要在标头中使用extern关键字将这些变量定义更改为变量声明

//player stats
extern std::string name;
extern double str;     //strength
extern double wis;     //wisdom
extern double ref;     //reflex
extern double hp;      //health points
extern double i;       //initiative
extern double inte;    //intelligence
extern double c;       //courage
extern int gold;       //gold
extern int xp;         //experience
extern int ap;         //armour points
extern int wd;         //weapon damage
extern int lvl;        //level
extern int sp;         //skill points

这将允许任意数量的文件#include此标头,因为它们实际上都没有定义变量; 他们只是宣布变量将存在于某处。 然后,您应该创建一个新的 .cpp 文件,可能是 globals.cpp,它实际上定义了变量:

#include "globals.h"

std::string name;
double str;     //strength
double wis;     //wisdom
double ref;     //reflex
double hp;      //health points
double i;       //initiative
double inte;    //intelligence
double c;       //courage
int gold;       //gold
int xp;         //experience
int ap;         //armour points
int wd;         //weapon damage
int lvl;        //level
int sp;         //skill points

这些是变量的实际定义,由于它们只存在于一个地方 (globals.cpp),因此您不会再遇到任何链接器错误。

希望这可以帮助!

你的 C++ 代码有很多问题

  • 切勿直接在触发多个符号的标头中声明全局变量,因为它们将出现在每个编译单元中(使用它们的 ~cpp 文件)一种解决方案是将它们设为 extern,但我建议您使用类或结构而是持有这些参数。

除此之外:

  • 永远不要在全局范围内的头文件中执行“使用命名空间 xxx”。 您将强制使用标头的每个人都将符号拉入全局命名空间中。
  • 它不遵循 C++ 语义,看起来更像 C(我真的会将所有玩家统计信息包装在同名的类中!)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM