C++编译时/运行时选项和参数,如何处理?

C++ compile-time / runtime options and parameters, how to handle?

在通用库中处理编译时和运行时选项的正确方法是什么?对于用户选择太多而无暇顾及其中大部分选项的大型软件,什么是好的做法?

假设任务是编写一个大型库来同时对多个数据集进行计算。执行这些计算的方法有很多种,库必须是高度可配置的。通常,存在与如何作为一个整体执行计算相关的选项。然后,每个数据集都有自己的一组计算选项。最后,每个计算都有一些调整参数,也必须设置。

库本身是通用的,但使用该库的每个应用程序都将使用特定类型的数据集,为此调整参数将采用特定值。因为它们在应用程序的整个生命周期中都不会改变,所以我在应用程序 编译时 中让它们为人所知。我在库中实现这些调整参数的方法是通过 Traits class,其中包含作为 static const 元素的调整参数。最终值的校准是应用程序开发的一部分。

数据集当然会根据用户向应用程序提供的内容而改变,因此还必须提供许多 运行时 选项(具有智能默认值)。校准它们的默认值也是应用程序开发的一部分。我会将这些选项实现为包含这些选项的 Config class,并且可以在应用程序启动时更改(例如解析配置文本文件)。它被传递给库中许多 classes 的构造函数。然后每个 class 调用 Config::get_x 以获得他们的特定选项 x

我不太喜欢这种设计的一点是,TraitsConfig class 都破坏了封装。一些选项与库的某些部分有关。然而,大多数时候,他们没有。让它们突然并排在一起让我很烦,因为它们会影响代码中的不同事物,而这些事物通常位于不同的抽象层中。

我正在考虑的一个解决方案是对这些不同的部分使用多个 public 继承。 class 需要知道一个选项,然后转换 Config 对象或调用相关的 Trait 父对象来访问它。此外,将 Config 传递给每个需要它(或其成员需要它)的 class 是非常不雅的。也许 Config 应该是单例?

您可以将参数放在一个名为 Config 的结构中(以保持您的话)并使其成为单例。

封装对于保持 classes 的一致性很重要,因为 class 自己负责。但是在您的配置 class 必须可供所有人访问的情况下,这是必要的。此外,向这种类型的 class 添加 getter 和 setter 只会增加开销(在最好的情况下,您的编译器可能只是内联它)。

另外,如果你真的想要一个 Traits class 来实现编译时参数,你应该只需要一个初始化函数(比如你的库的构造函数)。