C++ 算法的通用选项设计
我想知道是否有一种设计模式可以指定一组算法的选项。我用的是C++。 让我描述一下我的问题。我有一套算法,这些算法有不同的选择。我想设计一个单点访问这些算法。类似于战略模式的东西。此单点访问是一个控制器类,它将输入作为通用选项类。根据选项,将使用合适的算法。我想概括这些选项,以便扩展算法和客户端。 谢谢C++ 算法的通用选项设计,c++,design-patterns,C++,Design Patterns,我想知道是否有一种设计模式可以指定一组算法的选项。我用的是C++。 让我描述一下我的问题。我有一套算法,这些算法有不同的选择。我想设计一个单点访问这些算法。类似于战略模式的东西。此单点访问是一个控制器类,它将输入作为通用选项类。根据选项,将使用合适的算法。我想概括这些选项,以便扩展算法和客户端。 谢谢 Amol一种常用的模式是创建一个策略类,该类作为模板类型传递给您的类,然后从中继承: template <typename Policy> class fancy_algorithm
Amol一种常用的模式是创建一个策略类,该类作为模板类型传递给您的类,然后从中继承:
template <typename Policy>
class fancy_algorithm : private Policy {
};
我同意康拉德关于基于政策的设计的观点。我也推荐。在这本书之后,你的C++的愿景将永远改变;p> 在此基础上,如果您的算法在构造时需要参数,您可以通过要求任何
策略
类具有名为参数
的嵌套类型来干净地处理此问题,然后在fancy_算法
中提供一个构造函数,该构造函数接受此类型的参数并将其传递给包含的策略
对象:
template <typename Policy>
class fancy_algorithm : private Policy {
public:
typedef typename Policy::Params Params; // Need to redeclare :(
explicit fancy_algorithm(Params params = Params()) : Policy(params) {}
};
有趣!起初我想:为什么要从中衍生?这不是一种“是”与“是”的关系。但是仔细想想,这是有道理的:我们继承了选项的所有getter/setter,这非常方便,所以我们可以从外部设置它们。@dehmann:是的,这是违反直觉的。然而,私有继承并不是“is-a”关系的模型,而是“根据实现”。私有继承本身是一个非常容易混淆的概念,因为它与公共继承完全无关。基本上,私有继承是…(续):…只是类(组合)中私有成员身份的一种方便表示法。不要使用它,除非在上述奇怪的情况下。这是一个特殊的情况,因为它已经成为语言的成语,许多C++库作者立即知道在上下文中的含义。如果您的算法在构造时需要参数,则可以通过要求任何策略类都有一个嵌套类型称为PARAMs来处理这个问题。然后在fancy_算法中提供一个构造函数,该构造函数接受这种类型的参数并将其传递给包含的策略对象。j_random_hacker:非常好的评论,完全忘记了这些。用这个技巧自己做一个答案怎么样?评论并不是一个好地方。你会得到我的支持票这让我更加认真地思考政策课。谢谢
template <typename Policy>
class fancy_algorithm : private Policy {
public:
typedef typename Policy::Params Params; // Need to redeclare :(
explicit fancy_algorithm(Params params = Params()) : Policy(params) {}
};
struct multiply_by_params {
multiply_by_params(int x /* = 42 */) : _x(x) {} // See bottom
int get() const { return _x; } // Or, just make multiply_by a friend
private:
int _x;
};
struct multiply_by {
typedef multiply_by_params Params;
multiply_by(Params p) : _x(p.get()) { /* Other initialisation */ }
// Other code implementing the strategy (e.g. an operator()())
...
private:
int _x;
};
fancy_algorithm<multiply_by> a(69); // Always compiles
fancy_algorithm<multiply_by> b; // Compiles iff /* = 42 */ is uncommented