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



在泛型库中处理编译时和运行时选项的正确方法是什么?对于用户有太多选项而烦恼的大型软件来说,什么是好的做法?

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

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

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

我不太喜欢这种设计的一点是,Traits类和Config类都破坏了封装。某些选项与库的某些部分相关。然而,大多数时候,他们不会。让它们突然彼此相邻让我很恼火,因为它们会影响代码中的不同内容,这些内容通常位于不同的抽象层中。

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

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

封装对于保持类的一致性很重要,因为类对自身负责。但是,在您的情况下,每个人都必须可以访问 Config 类,这是必要的。此外,将 getter 和 setter 添加到这种类型的类只会增加开销(在最好的情况下,编译器可能只是内联它)。

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

最新更新