Question

I'm trying to implement a configuration manager class in c++11 that would load settings from *.xml files. The first implementation (I used structs instead of classes only for easy testing):

struct ConfigManager
{
    ConfigManager(){}

    void initialize()
    {
        add<CoreSettings>(std::make_unique<CoreSettings>("WhatEver.xml"));
    }

    template <typename T>
    void add(std::unique_ptr<T> settings)
    {
        settings_.insert(std::make_pair(std::type_index(typeid(T)), std::move(settings)));
    }

    template <typename T>
    T& get() const
    {
        auto it = settings_.find(std::type_index(typeid(T)));
        return dynamic_cast<T&>(*it->second);
    }

    void load()
    {
        for (auto& s : settings_)
            s.second->load();
    }

    void save()
    {
        for (auto& s : settings_)
            s.second->save();
    }

    std::map<std::type_index, std::unique_ptr<ISettings>> settings_;
};

It would allow me to write code like below to use this class:

ConfigManager confManager;
confManager.initialize();
confManager.load();
auto& coreSettings = confManager.get<CoreSettings>();
coreSettings.windowOptions_.height_ = 800;
confManager.save();

A more simple implementation would be:

struct ConfigManager : public IConfigManager
{
    ConfigManager()
    {
        set_.insert(&coreSettings_);
    }

    virtual void load() final
    {
        for (auto& s : set_)
            s->load();
    }

    virtual void save() final
    {
        for (auto& s : set_)
            s->save();
    }

    virtual CoreSettings& getCoreSettings() final
    {
        return coreSettings_;
    }

    CoreSettings coreSettings_;
    std::set<ISettings*> set_;
};

But this way I have to write a lot of getters for all kind of settings I will create.

Which one do you think it's better and why? Maybe this is not at all how it should be done; your opinion is appreciated.

Was it helpful?

Solution

I'd prefer option #1, precisely because it doesn't need to know of all setting types in advance. However, you should add some error checking into get() to react to a situation when the appropriate setting is not found (and thus it == settings_.end()).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top