【问题标题】:How do I load custom "const" variables from a config file in C++?如何从 C++ 中的配置文件加载自定义“const”变量?
【发布时间】:2016-08-02 13:23:07
【问题描述】:

我目前有一个从配置文件加载变量的函数。它使用这些来初始化一组常量配置变量。

// header file
namespace cfg {
    extern const char *config_value;
}

// source file 
namespace cfg {
    const char *config_value;
}

bool load_config() {
    cfg::config_value = load_config_line("config_value");
}

const char *load_config_line(const char *key) {
       // read value from config.cfg...
}

这很好用。问题是现在我想在其他几个项目中重用这段代码,这意味着常量值必须改变。这意味着在代码中的四个不同位置更改config_value 名称。这也意味着我有几个基本相同的代码副本要在不同的项目中维护。

有没有办法使用相同的代码来设置不同的常量值集以进行读取和解析?也许我所要做的就是更改头文件,它会自动找到这些值配置文件中的名称?棘手的部分是理想情况下,面向外部的配置值本身应该是恒定的并且在编译时可用(例如,使用字符串到值映射是不可取的,因为我希望有编译时保护) .

【问题讨论】:

  • 您应该使用已经实现的“序列化程序”并将数据存储和重新加载到结构/类实例,而不是重新发明轮子并处理全局变量。
  • @Klaus 抱歉,您能否详细说明“序列化程序”?
  • 请使用您最喜欢的搜索引擎 :-) 有很多库提供了从 c++ 数据结构读取/写入数据到文件/网络/数据库的方法。 boost.org/doc/libs/1_59_0_b1/libs/serialization/doc/index.html

标签: c++ c++11 config


【解决方案1】:

这里的解决方案是不使用全局变量,而是使用一些 settings 结构,您可以使用从文件中加载的值显式初始化这些结构。 struct 实例本身不需要是 const(您需要能够将值加载到其中,除非您在构造时传递所有内容),但对它的所有访问都应该是 const。最后一位可以通过传递settings 来实现,例如const settings& 到任何需要的地方。

int main()
{
    // Variant A: 2-step init
    settings s;
    s.loadConfigFile(filename);
    // Variant B: 1-step init - can make instance itself const
    const settings s(filename);

    Thing worker(s); // Thing::Thing(const settings&)
    worker.work();
}

当然,Worker 可以是您心中想要的任何东西。

请注意,设置本身不需要任何特殊的常量:

struct settings
{
    std::string config_value;
}

外部const 保护对其中包含的值的访问。

【讨论】:

  • 这很有用,它让我走到了那一步。但是我仍然需要为每个新的struct settings(在不同的项目中)编写loadConfigFile 函数吗?这就是我试图避免的。我需要一个loadConfigFile(settings set, std::string filename),它可以采用任意结构
  • @Drgabble 如果您需要任何任意结构,则需要将设置存储为例如std::unordered_map<std::string, std::string>std::unordered_map<string, boost::variant<int,double, std::string>> 或其他。如果有结构,您需要决定是否要为每个配置结构使用单独的 settings 结构。它是运行时与程序时间的权衡。
  • 那么没有办法让单独的settings 结构具有相同的loadConfig() 函数吗?是的,我想我想在这里两全其美……那么没有反射型的方法吗?还是我对 Java 的思考太多了?
  • @Drgabble 这段代码已经适用于任意结构。但实际上,不要自己实现,使用现有的 INI、YAMLJSONTOML 库。
  • @Drgabble 有很多方法可以解决这个问题。我建议你问一个详细的问题以获得正确的答复。现在我们都只是猜测和建议一些甚至可能没有必要的东西。
猜你喜欢
  • 2019-07-16
  • 2019-10-26
  • 2010-10-05
  • 2012-11-13
  • 2019-07-27
  • 1970-01-01
  • 1970-01-01
  • 2020-08-02
  • 2023-04-07
相关资源
最近更新 更多