Ошибка нескольких символов C++
Я думал 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__
Тогда есть два других файла cpp, которые включают "Library.h".
2 ответа
Проблема в том, что в вашем заголовочном файле 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
Это позволит любое количество файлов #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 использует их). Одним из решений было бы сделать их внешними, но я призываю вас использовать класс или структуру удерживая эти параметры вместо.
Кроме того:
- Никогда не делайте "использование пространства имен xxx" внутри заголовочных файлов в глобальной области видимости. Вы заставите всех, кто использует заголовок, тянуть символы в глобальном пространстве имен.
- Это не следование семантике C++, больше похоже на C (я бы действительно обернул всю статистику игрока внутри класса с тем же именем!)