如何使用OO一般表示一个参数?

时间:2011-01-04 11:47:58

标签: c++ design-patterns oop

在C ++中,我必须实现几种算法,它们代表了计算同一事物的不同方法。

我考虑使用接口来表示不同的算法。

class AlgorithmInterface
{
  public:
    virtual double ComputeSomething(void* parameter) = 0;
}

class AlgorithmImplementation1: public AlgorithmInterface
{
  public:
    virtual double ComputeSomething(void* parameter) { /* implementation */}
}

class AlgorithmImplementation2: public AlgorithmInterface
{
  public:
    virtual double ComputeSomething(void* parameter) { /* implementation */}
}

然而,每个参数(前一个例子中的void *)都不同,我如何一般地表示它们?

我在示例中使用了void *,因为我不知道如何表示这个。请告诉我应该怎么做:我应该为参数创建等效继承并转换它们吗? (这对我来说似乎很难看)

5 个答案:

答案 0 :(得分:9)

您可以在构造函数中传递参数 另外,将虚拟成员设为私有,并使对象成为仿函数:

class AlgorithmInterface
{
  public:
     double operator()() {return this->ComputeSomething();}
  private:
    virtual double ComputeSomething() = 0;
}

class AlgorithmImplementation1: public AlgorithmInterface
{
    virtual double ComputeSomething() { /* implementation */}
    public:
        AlgorithmImplementation1(Parameter 1);
}

class AlgorithmImplementation2: public AlgorithmInterface
{
    virtual double ComputeSomething() { /* implementation */}
    public:
        AlgorithmImplementation2(Item a1,Item a2);
}

int main()
{
    AlgorithmImplementation2   job(Item(12), Iterm(13));

    double result = job(); // execute;
}

答案 1 :(得分:3)

(基于我对您的问题的理解)如果计算保持不变且只是参数类型不同,那么您可以使用templates ..

答案 2 :(得分:1)

要么使用经典的OO(运行时)多态,在这种情况下,参数需要是基类指针/引用,可以将派生类对象传递给它,或者切换到模板和编译时多态,如STL所做的那样,并将算法和参数作为模板参数的实例传递。

使用模板,这就是您的代码的样子:

class AlgorithmImplementation1
{
  public:
    virtual double ComputeSomething(Param1* parameter) const
    { /* implementation */}
}

class AlgorithmImplementation1
{
  public:
    virtual double ComputeSomething(Param2* parameter) const
    { /* implementation */}
}

template< typename Algorithm >
void use_algorithm(const Algorithm& algorithm)
{
  // ...
  // get_parameter() _must_ return whatever the algorithm takes
  double d = algorithm( get_parameter() );
  // ...
}

Param1 get_parameter();

void f()
{
  use_algorithm( AlgorithmImplementation1() );
}

答案 3 :(得分:1)

另一种可能性是将“参数流”传递给算法。算法可以引用ParameterStream。

然后,派生算法将相应地从流中提取适当类型(数量)的参数。该流实现了参数的类型安全提取(反序列化),也可以实现(如果需要)版本控制。

这种可能性恕我直言的优势在于,即使将来不同的算法需要不同数量的参数,您也可以保持接口不可变。

所以基本上你会发送一个包含所需参数的序列化形式的参数,并在算法实现中根据需要对它们进行反序列化/验证。

如前所述,如果在编译时事情明确,模板也可以选择。

答案 4 :(得分:0)

真的需要继承吗?如果你这样做,那么模板化功能将不是一个选项(即你不能拥有虚拟功能模板 - 至少在当前标准中)并且Martin的解决方案可以工作。如果你不需要继承,那么下面就足够了

class AlgorithmImplementation1
{
  public:
    template <typename ParamType>
      double ComputeSomething(ParamType const& parameter) { /* implementation */}
}

class AlgorithmImplementation2
{
  public:
    template <typename ParamType>
      double ComputeSomething(ParamType const& parameter) { /* implementation */}
}

这当然取决于您计划如何使用parameter,如果您{{1},您可能最好使用重载(例如,将intstring区别对待)有一个一致的接口,那么函数模板就足够了。