5

我正在开发一个用于模拟真实世界场景的 C++ 应用程序。基于这个模拟,我们的团队将开发、测试和评估在这样一个真实世界场景中工作的不同算法。

我们需要定义几个场景的可能性(它们可能在一些参数上有所不同,但未来的场景可能还需要创建新类的对象)和维护一组算法的可能性(同样是一组参数,但还有要创建哪些类的定义)。参数被传递给构造函数中的类。

我想知道哪个是管理所有场景和算法配置的最佳方式。应该很容易让一个开发人员使用“他的”算法处理一个场景,而另一个开发人员使用“他的”不同算法处理另一个场景。尽管如此,参数集可能很大并且应该是“可共享的”(如果我在场景 A 中为某个算法定义了一组参数,则应该可以在场景 B 中使用该算法而无需复制和粘贴)。

似乎有两种主要方法可以完成我的任务:

  • 定义可以处理我的要求的配置文件格式。这种格式可能是基于 XML 的或自定义的。由于 C++ 中没有类似 C# 的反射,因此每次将新算法类添加到项目时,我似乎都必须更新配置文件解析器(以便将“MyClass”之类的字符串转换为 MyClass 的新实例)。我可以为每个设置创建一个名称并将此名称作为命令行参数传递。

    • 优点是:更改参数并重新运行无需编译,我可以轻松地将整个配置文件与模拟结果一起存储
    • 对比:似乎需要付出很多努力,尤其是困难,因为我使用了很多必须使用给定模板参数实例化的模板类。没有 IDE 支持写入文件(至少没有创建整个 XSD,每次添加参数/类时我都必须更新它)
  • 用 C++ 代码连接所有内容。我不完全确定如何做到这一点来分离所有不同的创建逻辑,但仍然能够跨场景重用参数。我想我也会尝试给每个设置一个(字符串)名称,并使用这个名称通过命令行 arg 选择设置。

    • pro:类型安全,IDE 支持,不需要解析器
    • 缺点:如何轻松存储设置和结果(可能是一些序列化?)?,每次参数更改后都需要编译

现在这里是我的问题: - 你的意见是什么?我错过了重要的优点/缺点吗?- 我错过了第三个选项吗?- 有没有一种简单的方法来实现给我足够的灵活性的配置文件方法?- 你将如何组织所有工厂代码在第二个方法中?有没有像这样的好 C++ 示例?

非常感谢!

4

3 回答 3

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并调用该函数以创建相应的对象。

于 2011-03-28T19:04:59.323 回答
0

如果您不使用 XML,则 boost::spirit 可能会至少使您面临的一些问题短路。这是一个简单的示例,说明如何将配置数据直接解析为类实例。

于 2010-09-14T13:32:37.393 回答
-1

我发现这个网站有一个很好的模板支持工厂,我认为它将在我的代码中使用。

于 2010-09-15T07:48:43.123 回答