C ++中的抽象函数

时间:2012-07-05 20:15:38

标签: c++

我想写一个抽象基类

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类型的对象,因为它是抽象的。我可以传递一个指向函数的指针,但是使用像f这样的f->operator()(num)似乎违背了操作符重载的精神。 ((*f)(num)更好,但仍然。)

有没有办法让运算符重载和这样的抽象很好地一起玩?

5 个答案:

答案 0 :(得分:3)

您只需将引用传递给您的函数:

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

答案 1 :(得分: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);

答案 2 :(得分:0)

似乎显而易见的答案是传递引用,所以你只需使用:f(num),就像往常一样。

除非你需要在运行时能够使用不同的函数对象(例如,有一个不同类型的仿函数数组,并在循环中调用它们),你可以考虑让函数被调用一个模板参数代替:

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

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

答案 3 :(得分:0)

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

除此之外,如果你想要运行时多态行为,那么你的operator()应该在基类中是虚拟的(在复制到问题时可能会被遗漏? - 没有virtual 纯-specifier =0形成不良)

答案 4 :(得分: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);
    }