我真的不知道如何解释我所面临的问题。这也让我很难在网上搜索答案。但我希望通过下面的代码示例可以澄清这个问题。
struct ISetting
{
virtual void* GetValue() = 0;
};
template<typename T>
struct Setting : public ISetting
{
T value;
void* GetValue()
{
return &value;
}
};
struct Settings
{
Setting<int> setting1;
Setting<std::string> setting2;
std::vector<ISetting*> allSettings;
Settings()
{
allSettings.push_back(&setting1);
allSettings.push_back(&setting2);
}
};
int main()
{
Settings settings;
settings.setting1.value = 5;
settings.setting2.value = "testing";
for(int i=0; i<settings.allSettings.size(); i++)
{
void* value = settings.allSettings[i]->GetValue();
printf("value = ...\n");
}
return 0;
}
Try this code
如您所见,我有一个包含设置的结构。这些设置可以是不同的类型。现在我想把这些设置保存到flash中(这在微控制器上运行),所以我想循环所有的设置并相应地写下来。问题是,我不知道设置的类型,因为该类型由于接口而丢失。为了简化问题,我想将每个设置的值打印到输出。而不是写到flash。
我确实想出了一个解决办法,但我不确定这是正确的方法。一般的想法是设置通过其界面接受访问者。然后,实现的设置调用访问者中的适当函数,并将其本身作为变量。然后,该访问者知道如何处理此设置。
template<typename T>
struct Setting;
struct ISettingVisitor
{
virtual void Visit(Setting<int>* setting) = 0;
virtual void Visit(Setting<std::string>* setting) = 0;
};
struct ISetting
{
virtual void Accept(ISettingVisitor* handler) = 0;
};
template<typename T>
struct Setting : public ISetting
{
T value;
void Accept(ISettingVisitor* handler)
{
handler->Visit(this);
}
};
struct Settings
{
Setting<int> setting1;
Setting<std::string> setting2;
std::vector<ISetting*> allSettings;
Settings()
{
allSettings.push_back(&setting1);
allSettings.push_back(&setting2);
}
};
struct SettingsPrinter : public ISettingVisitor
{
void Visit(Setting<int>* setting) { printf("value = %d\n", setting->value); }
void Visit(Setting<std::string>* setting) { printf("value = %s\n", setting->value.c_str()); }
};
int main()
{
Settings settings;
settings.setting1.value = 5;
settings.setting2.value = "testing";
SettingsPrinter settingsPrinter;
for(int i=0; i<settings.allSettings.size(); i++)
{
settings.allSettings[i]->Accept(&settingsPrinter);
}
return 0;
}
Try this code
假设我想将设置导出为JSON格式。这将是沿着如下:
struct JSONExporter : public ISettingVisitor
{
JSON* json = NULL;
void Visit(Setting<int>* setting) { json->AddInt(setting->name, setting->value); }
void Visit(Setting<std::string>* setting) { json->AddString(setting->name, setting->value); }
std::string Export(Settings* settings)
{
json = new JSON();
for(int i=0; i<settings.allSettings.size(); i++)
{
settings.allSettings[i]->Accept(this);
}
std::string result = json->ToString();
delete json;
return result;
}
};
我想这可以工作,但我不确定是否存在更精简的解决方案。
也许还有一个附带的问题
是否可以定义设置对象,使您不会忘记将设置添加到列表中。大概是这样的
struct Settings
{
MyIterableThing allSettings
{
Setting<int> setting1;
Setting<std::string> setting2;
};
Settings()
{
}
};
void main()
{
Settings settings;
settings.setting1.value = 5;
for (auto& it : settings.allSettings)
{
//Do something
}
}
1条答案
按热度按时间ccrfmcuu1#
你可以使用一个元组来代替基本的空指针向量: