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

pig*_*d10 6 c++ linker symbols

我想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__
Run Code Online (Sandbox Code Playgroud)

-

//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__
Run Code Online (Sandbox Code Playgroud)

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

tem*_*def 14

问题是在你的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     extern int ap;         //armour points
extern int wd;         //weapon damage
extern int lvl;        //level
extern int sp;         //skill points
Run Code Online (Sandbox Code Playgroud)

这将允许任意数量的文件#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
Run Code Online (Sandbox Code Playgroud)

这些是变量的实际定义,因为它们只存在于一个地方(globals.cpp),所以不会再出现任何链接器错误.

希望这可以帮助!

  • 这是完全正确的.包含防护措施会阻止您将一个文件最终包含在同一文件中的相同代码的两个副本,但是当您尝试将包含标题的多个文件链接在一起时会发生什么事情. (3认同)