我有2个头文件和1个源文件可供使用。分别为:Utility.h
,Game.h
和main.cpp
。我在Utility.h
中声明了外部变量,并尝试在main.cpp
中定义它们。这给了我一个未定义的参考错误,我不明白。我使用变量AFTER我给它一个值,所以应该没问题?
Utility.h:
#pragma once
#include <string>
#include <fstream>
#include <SDL.h>
namespace Utility {
extern std::string BIN_PATH;
extern std::string ROOT_PATH;
extern std::string EXE_PATH;
// Omitted rest of namespace.
}
的main.cpp
#include "Game.h"
int main(int argc, char * argv[]) {
// Get the necessary paths
std::string path = SDL_GetBasePath();
#ifdef _WIN32
// TODO check if working on different windows systems
// exePath = path;
// binPath = path.substr(0, path.find_last_of('\\'));
// rootPath = binPath.substr(0, binPath.find_last_of('\\'));
#elif __LINUX__
Utility::BIN_PATH = path.substr(0, path.find_last_of('/'));
Utility::ROOT_PATH = Utility::BIN_PATH.substr(0, binPath.find_last_of('/'));
// TODO check if working on different linux systems
#endif
std::cout << "BinPath: " + Utility::BIN_PATH << std::endl;
std::cout << "RootPath: " + Utility::ROOT_PATH << std::endl;
// Omitted rest of source.
}
我在Utility.h
中加载Game.h
,Game.h
加main.cpp
。在链接时,不应该将外部定义置于我的main.cpp
源之上吗?
答案 0 :(得分:1)
行
Utility::BIN_PATH = path.substr(0, path.find_last_of('/'));
Utility::ROOT_PATH = Utility::BIN_PATH.substr(0, binPath.find_last_of('/'));
不要定义变量。他们只是为他们分配价值。要定义它们,请使用:
std::string Utility::BIN_PATH;
std::string Utility::ROOT_PATH;
在全球范围内。为EXE_PATH
添加类似的行。
std::string Utility::EXE_PATH;
您也可以使用
定义它们namespace Utility
{
std::string BIN_PATH;
std::string ROOT_PATH;
std::string EXE_PATH;
}
确保这些行显示在.cpp文件中,而不是.h文件中。
答案 1 :(得分:1)
为了简化(相当复杂)规则,每个变量(以及其他实体)必须在整个程序中定义一次且仅定义一次。它可以多次声明。重要的是要了解什么是声明以及什么是定义。
extern std::string var; // in namespace scope
是字符串变量var
的声明。 var
尚未定义。你需要在其他地方定义它 - 只需一次 - 使用
std::string var; // in namespace scope!
在您的代码中,您没有在函数main
中定义变量 - 而是将值赋给它。但是需要定义变量。