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

C++中的灵活应用配置 我正在开发一个C++应用程序,用来模拟真实世界的场景。基于这个模拟,我们的团队将开发、测试和评估在这样一个真实场景中工作的不同算法,c++,configuration,configuration-files,factory,factory-pattern,C++,Configuration,Configuration Files,Factory,Factory Pattern,我们需要定义几个场景的可能性——它们可能在几个参数上有所不同,但未来的场景可能还需要创建新类的对象,以及维护一组算法的可能性,这也是一组参数,但也需要定义要创建的类。参数被传递给构造函数中的类 我想知道管理所有场景和算法配置的最佳方法是什么。一个开发人员使用他的算法处理一个场景,另一个开发人员使用他的不同算法处理另一个场景应该是很容易的。不过,参数集可能很大,应该是可共享的。如果我在场景a中为某个算法定义了一组参数,那么应该可以在场景B中使用该算法,而无需复制和粘贴 似乎有两种主要方法可以完成我

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

我想知道管理所有场景和算法配置的最佳方法是什么。一个开发人员使用他的算法处理一个场景,另一个开发人员使用他的不同算法处理另一个场景应该是很容易的。不过,参数集可能很大,应该是可共享的。如果我在场景a中为某个算法定义了一组参数,那么应该可以在场景B中使用该算法,而无需复制和粘贴

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

定义可以处理我的需求的配置文件格式。此格式可以是基于XML的,也可以是自定义的。由于C++中没有C类反射,所以每当我将一个新的算法类添加到Project中时,我必须更新配置文件解析器,以便将像MyClass这样的字符串转换成MyClass的新实例。我可以为每个设置创建一个名称,并将此名称作为命令行参数传递

优点是:无需编译即可更改参数并重新运行,我可以轻松地存储整个配置文件和模拟结果 contra:看起来需要做很多工作,特别是很难,因为我使用了很多必须用给定模板参数实例化的模板类。没有IDE支持编写文件,至少在不创建整个XSD的情况下是这样,每次添加参数/类时,我都必须更新整个XSD <>将所有的东西都用C++代码连接起来。我不完全确定如何将所有不同的创建逻辑分开,但仍然能够跨场景重用参数。我想我还应该尝试给每个设置一个字符串名称,并使用这个名称通过命令行arg选择设置

优点:类型安全,IDE支持,无需解析器 缺点:我怎样才能轻松地将结果存储在安装中?可能有些序列化???,每次参数更改后都需要编译 下面是我的问题: -你的意见是什么?我错过了吗 重要的优点/缺点? -我错过了第三个选择吗? -有没有一种简单的方法来实现提供 给我足够的灵活性? -您将如何在seconde方法中组织所有工厂代码?这里有没有什么好的C++例子?
非常感谢

如果不使用XML,boost::spirit可能会使您面临的一些问题短路。这里简单介绍了如何将配置数据直接解析为类实例。

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

有一种方法可以做到这一点,而无需模板或反射

首先,确保要从配置文件创建的所有类都有一个公共基类。让我们称之为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**FactoryFuncConfiguration*; std::映射名称到FactoryFunc; nameToFactoryFunc[MyClass1]=&create\u MyClass1; nameToFactoryFunc[MyClass2]=&create\u MyClass2; nameToFactoryFunc[MyClass3]=&create\u MyClass3


最后,解析配置文件并对其进行迭代,以查找指定类名的所有条目。当您找到这样一个条目时,您可以在nameToFactoryFunc表中查找它的工厂函数,并调用该函数来创建相应的对象。

谢谢,Steve。我以前没有见过这种情况,在配置文件中使用参数看起来很不错,但要获得我的模板参数似乎还有很多工作要做……通过使用相同的签名和不同的返回类型实现create_*函数,基本上你是手工完成模板的工作的。我并不是说这不好,但我认为如果使用一个模板化的create函数并为每个子类型专门化它会更清楚。关于调用哪个模板函数的决定是在编译时做出的。相反,使用name->factory函数映射可以在运行时做出决定,因此这是多态的一种形式。在编译时,只进行类型推断-您仍然可以保留pointe
rs到模板化函数——我必须承认,我无法创建函数模板的专门化映射。尽管签名和返回类型相同,但这些函数似乎有不同的类型。