简体   繁体   中英

How do I load custom “const” variables from a config file in C++?

I currently have a function which loads variables from a config file. It uses these to initialise a set of constant config variables.

// 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...
}

This works pretty well. The problem is that now I want to reuse this code in several other projects, which means the constant values have to change. This means changing the config_value names in four different places each in the code. It also means I have several copies of essentially the same code to maintain in different projects.

Is there a way of setting different sets of constant values using the same code for the reading and parsing? Perhaps so that all I have to do is change the header file and it automatically finds those value names in the config file? The tricky part is that ideally the outward facing config values themselves should be constant and available at compile time (using a string to value map for example is undesirable, as I would prefer to have the compile time protection).

The solution here is to not use global variables, and instead have some settings struct which you explicitly initialize with values loaded from the file. The struct instance itself doesn't need to be const (you'll need to be able to load the values into it, unless you pass everything in on construction), but all access to it should be const . This last bit can be achieved by passing settings as eg a const settings& to wherever it is needed.

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();
}

Of course Worker can be anything your heart desires.

Note that settings itself needs no special constness whatsoever:

struct settings
{
    std::string config_value;
}

It is the external const that guards access to the values contained within.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM