C++必知必会之(18)函数对象

来源:互联网 发布:ntfs for mac 14破解 编辑:程序博客网 时间:2024/06/13 01:45

1、与智能指针一样,函数对象也是一个普通的类对象。

智能指针类型重载->和*(可能还有->*)操作符,来模仿指针的行为;

而函数对象类型则重载函数调用操作符( ),来创建类似于函数指针的东西。


函数对象只是常规的类对象,但是可以采用标准的函数调用语法来调用它的operator()成员。

(此成员可能具有多个重载版本)。

Fib fib;

//....

cout<<"next two in series: "<<fib( )<<' '<<fib( )<<endl;


fib( )语法被编译器识别为对fib对象的operator( )成员函数的调用,这和fib.operator( )等价。


2、一个积分函数可以对low和high之间的值反复调用一个函数,来近似计算曲线所包围的面积,这是通过计算矩形面积的总和而实现的。

typedef double ( *F) ( douoble);

double integrate ( F f,  double low,  double high )   {

       const  int numsteps = 8;

       double  step = (high - low) / numsteps;

       double area = 0.0;

       while( low<high )    {

             area += f( low )  * step;

             low += step;

         }

        return area;

}

在这个版本中,传递一个函数指针来执行所期望的积分操作:

double aFunc( double x)    {   .....   }

//......

double area = integrate ( aFunc,  0.0,  2.71828 );

这种方法有效但不灵活,因为它使用一个函数指针来指示待整合的函数,但是它不能处理需要状态的函数或指向成员函数的指针。

一个替代的方式是创建一个函数对象层次结构。该层次结构的基类是一个简单接口类,只声明了一个纯虚operator( )。

class Func {

   public:

      virtual ~Func( );

      virtual  double  operator ( ) (double) = 0;

};

double integrate( Func &f,  double low, double high);


现在integrate能够与任何类型的Func函数对象进行整合。

integrate函数体不需要进行任何修改(当然重新编译一遍是免不了的),因为我们使用与调用函数指针相同的语法来调用一个函数对象。

例如,可以派生出一个能处理非成员函数的Func类型:

class NMFunc : public Func  {

   public:

       NMFunc ( double (*f) (double ) )   :  f_(f)     {     }

       double  operator( ) ( double d) {   return f_(d);  }

   private:

        double (*f_) (double);

};


这就允许整合所有最初版本的函数:

double aFunc( double x)   {   ...    }

//.....

NMFunc g( aFunc );

double area = integrate( g, 0.0, 2.78128);

 

原创粉丝点击