akr*_*roy 17 c++ constants global-variables configuration-files
我的目标是在我正在进行的C++游戏中使用全局常量(表示一些图形信息等).我目前的实现是将它们全部放在.h中并将它们包含在各处.这是有效的,除了每次更改设置时,必须重新编译整个代码库.
所以,我的下一个想法是将它们放在一些配置txt文件中并解析它们,这样在设置更改时实际上没有代码被更改.解析器很简单,我可以将值放入常量中,但由于解析器是一个代码块,因此常量不再是全局的.
有没有好办法解决这个问题?也许有些方法可以让它们成为全局,尽管它们处于阻塞或某种方式以避免在更改设置时重新编译所有内容?
Som*_*ude 21
我使用的解决方法是将变量放在一个单独的全局命名空间中,该命名空间位于名为like的头文件中config.h,然后在任何地方包含该文件.
// In config.h
#ifndef CONFIG_H
#define CONFIG_H
namespace config
{
extern int some_config_int;
extern std::string some_config_string;
bool load_config_file();
}
#endif
Run Code Online (Sandbox Code Playgroud)
在源文件中,您可以定义变量并将它们设置为默认值.此源文件还具有从配置文件加载变量的代码.
// In config.cpp
namespace config
{
int some_config_int = 123;
std::string some_config_string = "foo";
}
bool config::load_config_file()
{
// Code to load and set the configuration variables
}
Run Code Online (Sandbox Code Playgroud)
现在,在每个源文件中,您需要配置变量,包括config.h并访问它们config::some_config_int.
然而,没有"正确"的解决方法,所有工作方式都适合我的眼睛.
den*_*iro 17
另一种方法是创建一个单例类.
#include <fstream>
#include <map>
#include <string>
class ConfigStore
{
public:
static ConfigStore& get()
{
static ConfigStore instance;
return instance;
}
void parseFile(std::ifstream& inStream);
template<typename _T>
_T getValue(std::string key);
private:
ConfigStore(){};
ConfigStore(const ConfigStore&);
ConfigStore& operator=(const ConfigStore&);
std::map<std::string,std::string> storedConfig;
};
Run Code Online (Sandbox Code Playgroud)
这里的配置保存在映射中,这意味着只要parseFile可以读取文件并且getValue可以解析类型,如果添加新键,则无需重新编译config类.
用法:
std::ifstream input("somefile.txt");
ConfigStore::get().parseFile(input);
std::cout<<ConfigStore::get().getValue<std::string>(std::string("thing"))<<std::endl;
Run Code Online (Sandbox Code Playgroud)