全局函数与算子(Functor)
在C语言中,有函数指针。而c++的类的函数指针与具体类的方法相关联。
有时候,需要调用一对象的方法,显然此时可以将该对象作为参数传入函数。但这样却失去了很大的灵活性。不能用于回调函数。
这时Functor则有了用武之地。
什么是Functor?
说白了就是将类对象与方法绑定到一起,提供统一的接口。
下面举简单的例子说明:
#define FUNCTORFUN _cdecl
class A
{
public:
int i;
void FUNCTORFUN set(int in){i=in;}
};
template <class type> class B
{
public:
B(type* inp,void (FUNCTORFUN type::*fun)(int i))
{
p=inp;pFun=fun;
}
void Invoke(int i)
{
(p->*pFun)(i);
}
private:
type* p;
void (FUNCTORFUN type::*pFun)(int i);
};
void main()
{
A a;
B b(&a,&a::set);
b->Invoke(20);
}
说明:#define FUNCTORFUN _cdecl统一参数入栈方式。
A为一般的类,B为算子类。
往往将之用于回调函数:
class C
{
public:
C(){num=0;CallBackFun=NULL;}
int num;
void Run()
{
num++;
if (CallBackFun)
CallBackFun->Invoke(num);
}
B<A>* CallBackFun;
};
void main()
{
A a1;
B<A> b1(&a1,&A::set);
b1.Invoke(20);
C c1;
c1.CallBackFun=&b1;
for (int i=0;i<10;i++)
c1.Run();
}
更一般的可以定义纯虚基类:
class Functor
{
public:
virtual ~Functor() {}
virtual void invoke(void) = 0;
virtual const char *getName(void) { return myName.c_str(); }
virtual void setName(const char *name) { myName = name; }
protected:
std::string myName; //给每个算子起个名字
};
有一个参数算子基类
template<class P1>
class Functor1 : public Functor
{
public:
virtual ~Functor1() {}
virtual void invoke(void) = 0;
/**
@param p1 first parameter
*/
virtual void invoke(P1 p1) = 0;
};
可以实例化的算子类,类T中有一个只有一个参数的方法
template<class T, class P1>
class Functor1C : public Functor1<P1>
{
public:
Functor1C() {}
/**
@param func member function pointer
*/
Functor1C(T &obj, void (T::*func)(P1)) :
myObj(&obj), myFunc(func), myP1() {}
/**
@param func member function pointer
@param p1 default first parameter
*/
Functor1C(T &obj, void (T::*func)(P1), P1 p1) :
myObj(&obj), myFunc(func), myP1(p1) {}
/**
@param func member function pointer
*/
Functor1C(T *obj, void (T::*func)(P1)) :
myObj(obj), myFunc(func), myP1() {}
/**
@param func member function pointer
@param p1 default first parameter
*/
Functor1C(T *obj, void (T::*func)(P1), P1 p1) :
myObj(obj), myFunc(func), myP1(p1) {}
virtual ~Functor1C() {}
virtual void invoke(void) {(myObj->*myFunc)(myP1);}
/**
@param p1 first parameter
*/
virtual void invoke(P1 p1) {(myObj->*myFunc)(p1);}
/**
@param obj the 'this' pointer
*/
virtual void setThis(T *obj) {myObj=obj;}
/**
@param obj the 'this' pointer
*/
virtual void setThis(T &obj) {myObj=&obj;}
/**
@param p1 default first parameter
*/
virtual void setP1(P1 p1) {myP1=p1;}
protected:
T *myObj;
void (T::*myFunc)(P1);
P1 myP1;
};