3

我想写一个抽象基类

class func_double_double_t : public unary_function<double, double>
{
    virtual double operator()(double x) = 0;
};

并将其专门用于几种不同的类型

class func_pow_t : public func_double_double_t
{
 public:
    func_pow_t(double exponent) : exponent_(exponent) {};
    virtual double operator()(double x) { return pow(x, exponent_); };
}

class func_exp_t : public func_double_double_t
...

并在必要时将它们传递给函数:

double make_some_calculation(double num, func_double_double_t f)
{
     return f(x);
}

但是我不能定义一个类型的对象,func_double_double_t因为它是抽象的。我可以传递一个指向函数的指针,但首先使用flikef->operator()(num)似乎违背了运算符重载的精神。((*f)(num)更好,但仍然如此。)

有没有办法让运算符重载和这种抽象很好地结合在一起?

4

5 回答 5

3

您可以简单地将引用传递给您的函数:

double make_some_calculation(double num, func_double_double_t& f)
{
    return f(x);
}
于 2012-07-05T20:19:03.043 回答
1

虽然您可以通过将函数作为引用传递到那里,但 C++11 标准内置了以下仿函数类型:

double make_some_calculation(double d, std::function< double(double) > f) {
   return f(d);
}


...
auto add_2=std::bind( std::plus(), 2.0 );
double result=make_some_calculation(1.1, add_2);
于 2012-07-05T20:22:30.620 回答
0

似乎显而易见的答案是传递参考,因此您只需使用 : f(num),就像往常一样。

除非您需要能够在运行时使用不同的函数对象(例如,具有不同类型的函子数组,并在循环中调用它们),否则您可以考虑将要调用的函数作为模板参数:

template <class F>
double do_some_calculation(double num) { 
    return f(num);
}

如果要使用的函数在编译时是已知的,那么这通常是首选。

于 2012-07-05T20:19:00.793 回答
0

您可能需要重新审视几个基本概念。首先,您的问题的直接答案是您应该传递一个参考,它允许使用良好的语法并传递不同的派生实例。

除此之外,如果您想要运行时多态行为,那么您operator()应该在基类中是虚拟的(在复制到问题时可能会被忽略?--即没有纯说明符virtual的格式不正确) =0

于 2012-07-05T20:21:10.790 回答
0

如果您尝试通过运行时多态性来实现它,则需要以下内容

  1. 应声明基类函数virtual(它在哪里?)

    class func_double_double_t : public unary_function<double, double>
    {
        virtual double operator()(double x) = 0;
    };
    
  2. 从基类继承时派生类不需要virtual(为什么放在那里?)

    class func_pow_t : public func_double_double_t {
      ...
    
  3. 调用函数应该通过指针或引用接收对象

    double make_some_calculation(double num, func_double_double_t& f)
    {
      return f(x);
    }
    

    或者

    double make_some_calculation(double num, func_double_double_t* f)
    {
      return (*f)(x);
    }
    
于 2012-07-05T20:21:12.710 回答