我正在尝试在c ++ 11中实现一个配置管理器类,它将从* .xml文件加载设置。第一个实现(我使用结构代替类只是为了便于测试):
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_;
};
它允许我编写如下代码来使用这个类:
ConfigManager confManager;
confManager.initialize();
confManager.load();
auto& coreSettings = confManager.get<CoreSettings>();
coreSettings.windowOptions_.height_ = 800;
confManager.save();
更简单的实现是:
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_;
};
但是这样我必须为我将创建的所有类型的设置编写很多getter。
你觉得哪一个更好,为什么?也许这根本不应该怎么做;您的意见表示赞赏。
答案 0 :(得分:1)
我更喜欢选项#1,正是因为它不需要提前知道所有设置类型。但是,您应该在get()
中添加一些错误检查,以便在找不到适当的设置时做出反应(因此it == settings_.end()
)。