用于在C++中的对象之间共享数据的模式

sma*_*ill 10 c++ design-patterns

我已经开始将用FORTRAN编写的高能物理算法迁移到C++中面向对象的方法.FORTRAN代码在很多函数中使用了很多全局变量.

我已将全局变量简化为一组输入变量和一组不变量(变量在算法开始时计算一次,然后由所有函数使用).

此外,我将完整算法分为三个逻辑步骤,由三个不同的类表示.所以,以一种非常简单的方式,我有这样的事情:

double calculateFactor(double x, double y, double z)
{
    InvariantsTypeA invA();
    InvariantsTypeB invB();

    // they need x, y and z
    invA.CalculateValues();
    invB.CalculateValues();

    Step1 s1();
    Step2 s2();
    Step3 s3();

    // they need x, y, z, invA and invB
    return s1.Eval() + s2.Eval() + s3.Eval();
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 为了进行计算,所有InvariantsTypeXStepX对象都需要输入参数(这些不仅仅是三个).
  • 三个对象s1,s2并且s3需要的数据invAinvB对象.
  • 所有类通过组合使用其他几个类来完成它们的工作,所有这些类也需要输入和不变量(例如,s1有一个需要theta的类的成员对象,并且要构造).ThetaMatrixxzinvB
  • 我无法重写算法来减少全局值,因为它遵循几个高能物理公式,而那些公式就是这样.

是否有一个好的模式来共享输入参数和不变量到用于计算结果的所有对象?

我应该使用单身人士吗?(但calculateFactor功能估计大约一百万次)

或者我应该在创建对象时将所有必需的数据作为参数传递给它们?(但如果我这样做,那么数据将在每个类的每个成员对象中传递到处,造成混乱)

谢谢.

And*_*dry 3

好吧,在 C++ 中,根据您的约束和条件,最合适的解决方案是由指针表示。许多开发人员告诉您使用 boost::shared_ptr。好吧,这不是必需的,尽管它提供了更好的性能,特别是在考虑可移植性和对系统故障的鲁棒性时。

你没有必要绑定boost。确实,它们没有被编译,现在标准化进程将导致带有 boost 的 c++ 直接集成为标准库,但如果您不想使用外部库,显然也可以。

因此,让我们尝试仅使用 C++ 及其实际提供的功能来解决您的问题。

你可能会有一个 main 方法,在那里,你之前告诉过,初始化所有不变量元素......所以你基本上有常量,它们可以是每种可能的类型。如果您愿意,无需使它们保持不变,但是,主要是实例化不变元素并将它们指向所有需要使用它们的组件。首先在一个名为“common_components.hpp”的单独文件中考虑以下内容(我假设您需要一些类型来表示不变变量):

typedef struct {
   Type1 invariant_var1;
   Type2 invariant_var2;
   ...
   TypeN invariant_varN;
} InvariantType; // Contains the variables I need, it is a type, instantiating it will generate a set of global variables.
typedef InvariantType* InvariantPtr; // Will point to a set of invariants
Run Code Online (Sandbox Code Playgroud)

在你的“main.cpp”文件中你将有:

#include "common_components.hpp"
// Functions declaration
int main(int, char**);
MyType1 CalculateValues1(InvariantPtr); /* Your functions have as imput param the pointer to globals */
MyType2 CalculateValues2(InvariantPtr); /* Your functions have as imput param the pointer to globals */
...
MyType3 CalculateValuesN(InvariantPtr); /* Your functions have as imput param the pointer to globals */
// Main implementation
int main(int argc, char** argv) {
   InvariantType invariants = {
      value1,
      value2,
      ...
      valueN
   }; // Instantiating all invariants I need.
   InvariantPtr global = &invariants;
   // Now I have my variable global being a pointer to global.
   // Here I have to call the functions
   CalculateValue1(global);
   CalculateValue2(global);
   ...
   CalculateValueN(global);
}
Run Code Online (Sandbox Code Playgroud)

如果您有返回或使用全局变量的函数,请使用指向修改方法接口的结构的指针。通过这样做,所有更改都将被淹没到所有使用这些变量的地方。