声明变量时extern undefined reference错误
extern undefined reference error when declaring variable
我有 2 个头文件和 1 个源文件要使用。分别为:Utility.h
、Game.h
和main.cpp
。我已经在 Utility.h
中声明了外部变量,并试图在 main.cpp
中定义它们。这给了我一个未定义的参考错误,我不明白。我在给它赋值后使用变量,这样应该没问题吧?
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.
}
我在 Game.h
中包含 Utility.h
,在 main.cpp
中包含 Game.h
。链接时不应该将外部定义放在我的 main.cpp
源之上吗?
行
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 文件中。
为了稍微简化(相当复杂)规则,每个变量(以及其他实体)必须在整个程序中定义一次且仅定义一次。可以多次声明。了解什么是声明,什么是定义很重要。
extern std::string var; // in namespace scope
是字符串变量var
的声明。 var
尚未定义。您需要在其他地方定义它 - 只需一次 - 通过使用
std::string var; // in namespace scope!
在您的代码中,您没有在函数 main
中定义变量 - 相反,您正在为其赋值。但是需要定义变量。
我有 2 个头文件和 1 个源文件要使用。分别为:Utility.h
、Game.h
和main.cpp
。我已经在 Utility.h
中声明了外部变量,并试图在 main.cpp
中定义它们。这给了我一个未定义的参考错误,我不明白。我在给它赋值后使用变量,这样应该没问题吧?
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.
}
我在 Game.h
中包含 Utility.h
,在 main.cpp
中包含 Game.h
。链接时不应该将外部定义放在我的 main.cpp
源之上吗?
行
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 文件中。
为了稍微简化(相当复杂)规则,每个变量(以及其他实体)必须在整个程序中定义一次且仅定义一次。可以多次声明。了解什么是声明,什么是定义很重要。
extern std::string var; // in namespace scope
是字符串变量var
的声明。 var
尚未定义。您需要在其他地方定义它 - 只需一次 - 通过使用
std::string var; // in namespace scope!
在您的代码中,您没有在函数 main
中定义变量 - 相反,您正在为其赋值。但是需要定义变量。