function object(functor) ...

As is known,in many advanced programming languages(esp. object oriented ones) like c/c++,c#,Java,etc., the function is only one of the programming syntax constructs,unlike that in some pure interpreted programming lanuage such as Javascript,SmallTalk and so on,which are also object oriented,the function itself is a first-class object,however,for example:
 
function  Foo() {  //  note: Foo is an object
     this .sampleMemVar  =   123 ;
    
this .sampleMemFun  =   function () {};  //  create a new function object
     function () {};  //  anonymouse function object
     var  f  =   function (){};  //  equal to function f() {} declaration,also create new function object
};

 
As a result,foo can behaves in the same way as regular object do,that is to say,foo can have properties,member functions,and can be extended,see below:
 

Foo.prototype.sampleVar 
=   0 ;
Foo.prototype.sampleFun 
=   function (arglist) {};  //  prototype is one of the properties of object Foo
Foo.sampleStaticVar  =   " sample static variable " //  static variable
Foo.sampleStaticFun  =   function ()  //  extend Foo with a static function
var  foo  =   new  Foo();  //  applying new operator on a function object causing an instance of an Object is created with the members declared in the constructor,i.e.,Foo.
foo.toString();  //  inherited from Object
typeof (foo);  //  you can call typeof operator on foo,where Object is returned
typeof (Foo);  //  call tpyeof operator on Foo,where Function is returned
printf(Foo.sampleStaticVar);
foo.sampleMemVar 
=   100 //  access instance variable
Foo.sampleStaticFun();  //  call static method
foo.sampleMemFun();  //  call instance method

 
No need to enumerate the examples any more. You can see that the function has no much differences from general objects,except that it does inherites from Function on the other hand.
 
Then how about the situation in c/c++,or others?
For example, we have a function,which can perform some action on two operands,and the specified action can only be determined at runtime.Then how to solve this problem?
 
Of course,you can use (memebr) function pointer like:
 
typedef  int  ( * OpFunc)( int  left, int  right);


 
but you should first know the argument types and return type.
how about template?
 
template < class  _Arg1, class  _Arg2, class  _Result >
_Result(
* OpFunc)(_Arg1 arg1,_Arg2 arg2);  //  this does not compile

 
You could never use template directly on typedef or object declarations.
Then maybe you want to encapsulate the concept in this way:
 
template < class  _Arg1, class  _Arg2, class  _Result >
class  Performer
{
public :
 typedef _Result (
* OpFunc)(_Arg1,_Arg2);
 Performer(OpFunc _opfunc) : m_opfunc(_opfunc)
 {
  _ASSERT(NULL 
!=  _opfunc);
 }
 _Result Perform(_Arg1 arg1,_Arg2 arg2)
 {
  
return  m_opfunc(arg1,arg2);
 }
private :
 OpFunc m_opfunc;
};

 
Yes,this works. However,function pointer itself is not an object oriented construct,as a result,lack of flexibility and extensibility.
 
Then,if you're familar with c#,you may want to use delegate.
And unlike template in c++,you can apply generic on delegate directly.
 

delegate  _Result OpFunc < _Arg1,_Arg2,_Result > (_Arg1 arg1,_Arg2 arg2);
class  Performer < _Arg1, _Arg2, _Result >
{
    
private  OpFunc < _Arg1, _Arg2, _Result >  opfun  =   null ;
    
public  Performer(OpFunc < _Arg1, _Arg2, _Result >  _opfun)
    {
        
if  ( null   ==  _opfun)  throw   new  ArgumentException();
        
this .opfun  =  _opfun;
    }
    
public  _Result Perform(_Arg1 arg1, _Arg2 arg2)
    {
        
return  opfun(arg1, arg2);
    }
}

 
you can even implement you delegate in c++,only by making a wrapper to any function pointer.
No matter what you do with delegate,you are actually using function pointers,then again,lack of flexibility and extensibility.
 
So, why not use polymorphism?
If we can store the runtime action performer in an object,e.g.,action_performer,and we call the method on this object,where different object has different implementation for that action.
 

template
< class  _Arg1, class  _Arg2, class  _Result >
class  PerformerBase
{
public :
 
virtual  _Result Perform(_Arg1 arg1,_Arg2 arg2)  =   0 ;
};
template
< class  _Arg1, class  _Arg2, class  _Result >
class  AddPerformer :  public  PerformerBase < _Arg1,_Arg2,_Result >
{
public :
 _Result Perform(_Arg1 arg1,_Arg2 arg2)
 {
  
return  arg1  +  arg2;
 }
};
template
< class  _Arg1, class  _Arg2, class  _Result >
class  MinusPerformer :  public  PerformerBase < _Arg1,_Arg2,_Result >
{
public :
 _Result Perform(_Arg1 arg1,_Arg2 arg2)
 {
  
return  arg1  -  arg2;
 }
};

 
Yes,this also works and we can gain much flexibility and extensibility from this solution.
Then if we we can use function object as we do in Javascript,we can gain much more.
Forget operator overloading?( return to your c++ textbook for a look:-))
we can obtain a function object by encapsulate the function and overload it call operator,i.e.().
For example,
 
class  Functor
{
public :
    
int   operator ()( int  a, int  b) {  return  a  +  b; }
};
Functor myFuncObj;
int  x  =  myFuncObj( 1 , 2 );

 
Quite easy,right?
 
OK,then let's return to our problem,which is now trivial,given below:
 
template < class  _Arg1, class  _Arg2, class  _Result >
class  FunctorBase
{
public :
 
virtual  _Result  operator ()(_Arg1 arg1,_Arg2 arg2)  =   0 ;
};
template
< class  _Arg1, class  _Arg2, class  _Result >
class  AddFunctor :  public  FunctorBase < _Arg1,_Arg2,_Result >
{
public :
 _Result 
operator ()(_Arg1 arg1,_Arg2 arg2)
 {
  
return  arg1  +  arg2;
 }
};
template
< class  _Arg1, class  _Arg2, class  _Result >
class  MinusFunctor :  public  FunctorBase < _Arg1,_Arg2,_Result >
{
public :
 _Result 
operator ()(_Arg1 arg1,_Arg2 arg2)
 {
  
return  arg1  -  arg2;
 }
};
template
< class  _Arg1, class  _Arg2, class  _Result >
class  Performer
{
public :
 Performer(FunctorBase
< _Arg1,_Arg2,_Result >   &  functor)
  : m_functor(functor)
 {
 }
 _Result Perform(_Arg1 arg1,_Arg2 arg2)
 {
  
return  m_functor(arg1,arg2);
 }
private :
 FunctorBase
< _Arg1,_Arg2,_Result >   &  m_functor;
};

 
In conclusion, you can implement your own specific function object(functor) even in c++,c#,etc.,then you can use function as general objects in your program with high flexibility,resuability and extensibility. Actually, if you look into the STL,you will find that many functions receive a functor as a parameter,e.g.,find_if in <algorithm> receives a predictor as a searching criteria. see declaration below:
 
template < class  InputIterator,  class  Predicate >
   InputIterator find_if(
      InputIterator _First,
      InputIterator _Last,
      Predicate _Pred
   );

 
then you can call like this:
int  arr[]  =  { 1 , 2 , 3 , 4 , 5 };
int   *  found  =  find_if(arr,arr  +  _countof(arr),greater < int > ( 2 ));  //  find element that is greater thatn 2.
 

functors are declared in <functional> in STL.

你可能感兴趣的:(function object(functor) ...)