Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;传递大量参数的设计模式_C++_Algorithm_Design Patterns_Function_Parameters - Fatal编程技术网

C++ C++;传递大量参数的设计模式

C++ C++;传递大量参数的设计模式,c++,algorithm,design-patterns,function,parameters,C++,Algorithm,Design Patterns,Function,Parameters,我有一个相当大的类,它实现了几个逻辑相关的算法(来自图论)。大约需要10-15个参数作为算法的输入。算法不会对其进行修改,而是用于指导其操作。首先,我将解释实现此功能的两个选项。我的问题是这样做的常见方式是什么(无论是不是两种选择之一) 我个人不喜欢在N很大时将这些值作为参数传递给函数,尤其是在我还在开发算法的时候 void runAlgorithm(int param1, double param2, ..., bool paramN); 相反,我有一个包含算法的类Algorithm,还有一

我有一个相当大的类,它实现了几个逻辑相关的算法(来自图论)。大约需要10-15个参数作为算法的输入。算法不会对其进行修改,而是用于指导其操作。首先,我将解释实现此功能的两个选项。我的问题是这样做的常见方式是什么(无论是不是两种选择之一)

我个人不喜欢在
N
很大时将这些值作为参数传递给函数,尤其是在我还在开发算法的时候

void runAlgorithm(int param1, double param2, ..., bool paramN);
相反,我有一个包含算法的类
Algorithm
,还有一个包含这些参数的struct
AlgorithmGlobals
。我可以将此结构传递给:

void runAlgorithm(AlgorithmGlobals const & globals);
或者我向类中添加一个公共AlgorithmGlobals实例:

class Algorithm {
public:
    AlgorithmGlobals globals;
    void runAlgorithm();
}
然后在其他地方我会这样使用它:

int main() {
    Algorithm algorithm;
    algorithm.globals.param1 = 5;
    algorithm.globals.param2 = 7.3;
    ...
    algorithm.globals.paramN = 5;

    algorithm.runAlgorithm();

    return 0;
}
请注意,
AlgorithmGlobals
的构造函数为每个参数定义了良好的默认值,因此只需要指定具有非默认值的参数


AlgorithmGlobals
不是私有的,因为它们可以在调用
runAlgorithm()
函数之前自由修改。没有必要“保护”它们。

这就是所谓的“保护”,通常这是一件好事。我不喜欢会员版,尤其是称之为“XGlobals”,并暗示它在各地共享。相反,参数对象模式通常涉及创建参数对象的实例,并将其作为参数传递给函数调用。

我使用您已经提到的这种技术:

void runAlgorithm(AlgorithmGlobals const & globals);
但是将调用类
AlgorithmParams

其他人已经提到了参数对象,但是还有另一种可能性:使用

生成器允许您省略默认值合适的参数,从而简化代码。如果要将算法与多个不同的参数集一起使用,这一点尤其方便。OTOH它还允许您重用类似的参数集(尽管存在无意重用的风险)。这(连同方法链接)将允许您编写如下代码

Algorithm.Builder builder;

Algorithm a1 = builder.withParam1(1).withParam3(18).withParam8(999).build();
...
Algorithm a2 = builder.withParam2(7).withParam5(298).withParam7(6).build();
建议您为什么不这样做:

class Algorithm {
public:
Algorithm::Algorithm(AlgorithmGlobals const & globals) : globals_(globals) {}

    void runAlgorithm(); // use globals_ inside this function

   private:
    const AlgorithmGlobals globals_;
    };
现在您可以这样使用它:

AlgorithmGlobals myglobals;
myglobals.somevar = 12;

Algorithm algo(myglobals);

你有几个不同的想法,你应该建议你的设计:

  • 这些参数纯粹是输入
  • 这些参数特定于您的算法
  • 参数具有正常的默认值

  • 这就是我的建议。

    这里可能有用

    a.runAlgorithm() = Parameters().directed(true).weight(17).frequency(123.45);
    

    这是我最喜欢的解决方案。除此之外,由于OP表示在算法运行时参数保持不变,我将使其成为
    const AlgorithmGlobals\u globals。此外,领先的下划线保留在C++标准中。使用尾随下划线(即
    globals
    而不是
    \u globals
    )。
    \u globals
    在此上下文中不保留。回答得很好。我对StackOverflow有点陌生,现在我坐在那里,看着几个很棒的答案,不知道该选哪一个作为答案,哈哈。这一个太清楚了,描述得很好了!;-)@Lex Fridman-我会将参数传递给函数调用,除了调用类“Algorithm”,这意味着它基本上是对算法运行的封装。此外,我还必须进行编辑,因为我意识到
    参数的声明是非法的,除非
    参数的定义在类内。谢谢!:-)STL在其实现中大量使用了这种方法。
    
    a.runAlgorithm() = Parameters().directed(true).weight(17).frequency(123.45);