Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.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++_Algorithm_Class - Fatal编程技术网

C++ 习惯上把算法放到课堂上可以吗?

C++ 习惯上把算法放到课堂上可以吗?,c++,algorithm,class,C++,Algorithm,Class,我有一个复杂的算法。这将使用许多变量,在初始化时计算帮助器数组,并同时计算数组。由于算法很复杂,我将其分解为几个函数 现在,我实际上不明白从惯用的方式来看这是一个怎样的类;我的意思是,我只是习惯于将算法作为函数。其用法是: Calculation calc(/* several parameters */); calc.calculate(); // get the heterogenous results via getters 另一方面,将其放入类中具有以下优点: 我不必将所有变量传递给

我有一个复杂的算法。这将使用许多变量,在初始化时计算帮助器数组,并同时计算数组。由于算法很复杂,我将其分解为几个函数

现在,我实际上不明白从惯用的方式来看这是一个怎样的类;我的意思是,我只是习惯于将算法作为函数。其用法是:

Calculation calc(/* several parameters */);
calc.calculate();
// get the heterogenous results via getters
另一方面,将其放入类中具有以下优点:

  • 我不必将所有变量传递给其他函数/方法 在算法开始时初始化的数组可以在整个类中的每个函数中访问 我的代码更短(imo)更清晰
一种混合方法是将算法类放入源文件中,并通过使用它的函数访问它。算法的用户将看不到该类

有没有人有什么有价值的想法可以帮助我


提前非常感谢

这实际上归结为:算法是否需要访问不应该是公共的类的私有区域?如果答案是肯定的(除非你愿意根据具体情况重构你的类接口),你应该使用一个成员函数,如果不是,那么一个自由函数就足够了


以标准库为例。大多数算法都是作为自由函数提供的,因为它们只访问类的公共接口(例如,使用标准容器的迭代器)。

我想说,将算法(或者更好的,计算)表示为类是非常惯用的。OOP中对象类的定义之一是“数据和对该数据进行操作的函数”。compex算法及其输入、输出和中间数据与该定义完美匹配


我自己做过几次,它大大简化了(人工)代码流分析,使整个过程更易于推理、调试和测试。

您是否需要每次以完全相同的顺序调用完全相同的函数?那么,您不应该要求调用代码来执行此操作。将算法拆分为多个函数是可以的,但我仍然需要一次调用下一次,然后再调用下一次,以此类推,并在过程中传递结果/参数的结构。类不适合一次性调用某个过程


我对一个类执行此操作的唯一方法是,如果该类本身封装了所有输入数据,然后您对其调用
myClass.nameofMyGorithm()
,以及其他可能的操作。然后是数据+操纵器。但仅仅是操纵者?是的,我不太确定。

这取决于你想封装什么样的算法。一般来说,我同意约翰·卡马克的观点:“我的观点。”

我有一个复杂的算法。这将使用许多变量,在初始化时计算帮助器数组,并同时计算数组。[…]

现在,我实际上不明白从惯用的方式来看这是一个怎样的类

事实并非如此,但很多人都做和你一样的事情(我也做过几次)

<>而不是为算法创建类,考虑将输入和输出转换为类/结构。

也就是说,而不是:

Calculation calc(a, b, c, d, e, f, g);
calc.calculate();
// use getters on calc from here on
你可以写:

CalcInputs inputs(a, b, c, d, e, f, g);
CalcResult output = calculate(inputs); // calculate is now free function
// use getters on output from here on

这不会产生任何问题,并且执行相同(实际上更好)的数据分组。

如果客户机代码的抽象是一种算法,那么 可能希望保留一个纯功能接口,而不是 在那里介绍其他类型。这是很常见的 另一方面,在源代码中实现这样的函数 文件,该文件为其定义公共数据结构或类 内部使用,因此您可能有:

double calculation( /* input parameters */ )
{
    SupportClass calc( /* input parameters */ );
    calc.part1();
    calc.part2();
    //  etc...
    return calc.results();
}
根据代码的组织方式,
SupportClass
将 在源文件中的未命名命名空间中(可能是最 常见情况),或在“专用”标题中,仅由
在现代C++中涉及到的资源的来源,

的区别已经被侵蚀了不少。即使通过ANSI之前语言的运算符重载,您也可以创建一个实例在语法上类似于函数的类:

struct Multiplier
{
    int factor_;

    Multiplier(int f) : factor_(f) { }

    int operator()(int v) const
    {
        return v * _factor;
    }
};

Multipler doubler(2);
std::cout << doubler(3) << std::endl; // prints 6
这里,
doubler
是一个lambda,它本质上是一种声明编译器生成的类的实例的好方法,该类实现了
()
操作符

更准确地再现原始示例,我们需要一个名为
乘数
的类似函数的东西,它接受
因子
,并返回另一个类似函数的东西,它接受值
v
,并返回
v*因子

auto multiplier = [] (int factor)
{
    return [=] (int v) { return v * factor; };
};

auto doubler = multiplier(2);

std::cout << doubler(3) << std::endl; // prints 6
自动乘法器=[](整数因子)
{
return[=](int v){return v*factor;};
};
自动倍频器=倍频器(2);

std::cout如果你有持久状态,那么一定要创建一个类。我发现有一条规则很有用,那就是总是将参数作为函数参数传递(因为99.9%的bug来自于在共享状态下操作数据)——但是类确实有它们的用途,但我不知道它是否是惯用的,出于完全相同的原因,我一直都喜欢这样。这是一个从带有全局变量的算法的初始粗略变量的方便转换:
的随机数生成引擎是将状态封装在类中的算法的一个很好的例子。“算法”是一个名词,因此是一个对象。回答得好。事实上,我可能会强调,数据和算法应该成为一个类的实现,该类公开了更高级的逻辑。例如,与其使用“二进制搜索树的算法”,不如制作一个高级“地图”,等等@KerrekSB Yup,如果这是一个可以用来表达高级概念的算法,我100%同意。OTOH,我认为这更像是在一个复杂的模拟框架内“计算ODE集成”。在这里,我会说计算是更高层次的逻辑。我肯定会说,在我的例子中,计算本身就是高层次的
auto multiplier = [] (int factor)
{
    return [=] (int v) { return v * factor; };
};

auto doubler = multiplier(2);

std::cout << doubler(3) << std::endl; // prints 6