委托机制的本质就是调用成员函数的函数指针,实现回调

委托就是一种引用方法的类型.一旦为委托分配了方法,委托将与该方法具有完全相同的行为.委托方法的使用可以像其他任何方法一样,具有参数和返回值.委托可以看作是对函数的抽象,是函数的"类".委托的实例将代表一个具体的函数.

一个委托可以搭载多个方法,所有方法被依次唤起.它可以使得委托对象所搭载的方法并不需要属于同一个类.但委托对象所搭载的所有方法必须具有相同的原形和形式

#include <iostream>
#include <vector>
using namespace std;

class A{
public:
    void fun(){
        cout << "fun" << endl;
    }
};

class B{
public:
    void fun(int i){
        cout << "B::fun " << i << endl;
    }
};

class C{
public:
    void fun(int i){
        cout << "C::fun " << i << endl;
    }
};

void fun2(int i){
    cout << "fun2:" << i << endl;
}

template<typename T>
class DelegateHandler
{

public:
    DelegateHandler(T* pT, void (T::*pFun)()):
          mT(pT), mFun(pFun) { }

    void invoke()
    {
        (mT->*mFun)();
    }

private:
    T* mT;
    void (T::*mFun)();
};

//none member fun
template<>
class DelegateHandler<void>
{
public:
    DelegateHandler(void (*pFun)(int))
    {
        mFun = pFun;
    }
    void invoke(int i)
    {
        mFun(i);
    }

private:
    void (*mFun)(int);
};

class DelegateHandlerInterface
 {
public:
    virtual ~DelegateHandlerInterface(){ }
    virtual void invoke(int i) = 0;
};

template<typename T>
class DelegateHandlerImpl1: public DelegateHandlerInterface
 {
public:
    DelegateHandlerImpl1(T* pT, void (T::*pFun)(int)):
          mT(pT), mFun(pFun) { }
    virtual void invoke(int i){
        (mT->*mFun)(i);
    }
private:
    T* mT;
    void (T::*mFun)(int);
};

int main()
{
    A a;
    DelegateHandler<A> af(&a,&A::fun);
    af.invoke();
    DelegateHandler<void> vf(&fun2);
    vf.invoke(3);

    B b;
    C c;
    vector<DelegateHandlerInterface*> v;
    DelegateHandlerImpl1<B> impl1(&b,&B::fun);
    DelegateHandlerImpl1<C> impl2(&c,&C::fun);
    v.push_back(&impl1);
    v.push_back(&impl2);
    for (auto it = v.cbegin(); it != v.cend(); ++it) {
        (*it)->invoke(7);
    }
}


fun
fun2:3
B::fun 7
C::fun 7