我想写一个抽象基类
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)
更好,但仍然。)
有没有办法让运算符重载和这样的抽象很好地一起玩?
答案 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)
如果您尝试通过运行时多态实现它,则需要以下
基类函数应声明为virtual
(它在哪里?)
class func_double_double_t : public unary_function<double, double>
{
virtual double operator()(double x) = 0;
};
从基类继承时,派生类不需要virtual
(为什么要把它放在那里?)
class func_pow_t : public func_double_double_t {
...
调用函数应该通过指针或引用
接收对象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);
}