我正在开发一个用于模拟真实世界场景的C ++应用程序。基于此模拟,我们的团队将开发,测试和评估在这样一个现实世界中工作的不同算法。
我们需要定义几个场景的可能性(它们可能在一些参数上有所不同,但未来的场景可能还需要创建新类的对象)以及维护一组算法的可能性(同样是一组)参数以及定义要创建的类的定义。参数传递给构造函数中的类。
我想知道哪种是管理所有场景和算法配置的最佳方法。应该很容易让一个开发人员使用“他的”算法处理一个场景,而另一个开发人员使用“他的”不同算法处理另一个场景。尽管如此,参数集可能很大并且应该是“可共享的”(如果我在场景A中为某个算法定义了一组参数,那么应该可以在场景B中使用该算法而无需复制和粘贴)。
似乎有两种主要方法可以完成我的任务:
定义可以处理我的要求的配置文件格式。此格式可能是基于XML或自定义的。由于C ++中没有类似C#的反射,似乎每次将新算法类添加到项目时都必须更新配置文件解析器(为了将像“MyClass”这样的字符串转换为MyClass的新实例)。我可以为每个设置创建一个名称,并将此名称作为命令行参数传递。
用C ++代码连接所有内容。我不完全确定如何分离所有不同的创建逻辑,但仍然能够跨场景重用参数。我想我也会尝试为每个设置提供一个(字符串)名称,并使用此名称通过命令行arg选择设置。
现在我的问题是: - 你有什么意见?我错过了吗 重要的利弊? - 我错过了第三种选择吗? - 是否有一种简单的方法来实现给出的配置文件方法 我足够的灵活性? - 您如何在seconde方法中组织所有工厂代码?对于类似的东西,有没有好的C ++示例?
非常感谢!
答案 0 :(得分:2)
有一种方法可以在没有模板或反射的情况下做到这一点。
首先,确保要从配置文件创建的所有类都具有公共基类。我们称之为MyBaseClass
,并假设MyClass1
,MyClass2
和MyClass3
都从中继承。
其次,为MyClass1
,MyClass2
和MyClass3
中的每一个实现工厂函数。所有这些工厂功能的签名必须相同。示例工厂功能如下。
MyBaseClass * create_MyClass1(Configuration & cfg)
{
// Retrieve config variables and pass as parameters
// to the constructor
int age = cfg->lookupInt("age");
std::string address = cfg->lookupString("address");
return new MyClass1(age, address);
}
第三,在地图中注册所有工厂功能。
typedef MyBaseClass* (*FactoryFunc)(Configuration *);
std::map<std::string, FactoryFunc> nameToFactoryFunc;
nameToFactoryFunc["MyClass1"] = &create_MyClass1;
nameToFactoryFunc["MyClass2"] = &create_MyClass2;
nameToFactoryFunc["MyClass3"] = &create_MyClass3;
最后,解析配置文件并对其进行迭代,以查找指定类名称的所有条目。当您找到这样的条目时,在nameToFactoryFunc
表中查找其工厂函数并调用该函数来创建相应的对象。
答案 1 :(得分:0)
如果您不使用XML,则boost :: spirit可能会至少使您遇到的一些问题短路。这是一个简单的example如何将配置数据直接解析为类实例。
答案 2 :(得分:-1)
我发现this website有一个很好的模板支持工厂,我认为它将在我的代码中使用。