设为首页 加入收藏

TOP

c/c++:回调函数(三)
2015-07-24 05:45:30 来源: 作者: 【 】 浏览:13
Tags:c/c 函数
m_pMemberFunc)(para);
}
private:
T* m_pObj;
void (T::*m_pMemberFunc)(T1);
};

template
class signal
{
public:
void bind(T* pObj,void (T::*pMemberFunc)(T1 para))
{
m_slots.push_back(new slot (pObj,pMemberFunc));
}
~signal()
{
vector * >::iterator ite=m_slots.begin();
for (;ite!=m_slots.end();ite++)
{
delete *ite;
}
}
void operator()(T1 para)
{
vector * >::iterator ite=m_slots.begin();
for (;ite!=m_slots.end();ite++)
{
(*ite)->Execute(para);
}
}

private:
vector * > m_slots;
};

class receiver
{
public:
void callback1(int a)
{
cout<<"receiver1: "< }
void callback2(int a)
{
cout<<"receiver2: "< }
};


class sender
{
public:
sender(): m_value(0) {}
int get_value()
{
return m_value;
}
void set_value(int new_value)
{
if (new_value!=m_value)
{
m_value=new_value;
m_sig(new_value);
}
}
signal m_sig;
private:
int m_value;
};



int main(int argc,char** arg)
{
receiver r;
sender s;
s.m_sig.bind(&r,&receiver::callback1);
s.m_sig.bind(&r,&receiver::callback2);
s.set_value(1);
return 0;
} 复制代码 复制代码

程序在VC6下顺利通过,这个版本相比前面所说的继承手法耦合性低了,被调用者receiver与规定函数接口的slot类没有任何关系,但仔细以观察这个程序在概念上是有问题的,signal类有两个模板参数,一个是类的类型,一个是函数参数类型,如果把这个signal/slots组件提供出去,使用者如上面的sender类不免会有个疑虑:在实例化signal类型时,必须提供这两个模板参数,可是调用方事先哪就一定知道接收方(receiver)的类型呢,而且从概念上讲事件发送方与接收方只需遵循一个共同的函数接口就可以了,与类没什么关系,上个程序要求在实例化时就得填充receiver的类型,也就决定了它与receiver只能一对一,而不能一对多,于是作此改进:将signal的参数T去掉,将T类型的推导延迟到绑定(bind)时,signal没有参数T,signal的成员slot也就不能有,那slot的成员也就不能有,可是,参数T总得找个地方落脚啊,怎么办?有个窍门:让slot包含slotbase成员,slotbase没有参数T的,但slotbase只定义接口,真正的实现放到slotimpl中,slotimpl就可以挂上参数T了,boost中any、shared_ptr就是用此手法,改进后全部代码如下:

复制代码 复制代码 #include
#include
using namespace std;

template
class slotbase
{
public:
virtual void Execute(T1 para)=0;
};

template
class slotimpl : public slotbase
{
public:
slotimpl(T* pObj,void (T::*pMemberFunc)(T1))
{
m_pObj=pObj;
m_pMemberFunc=pMemberFunc;
}
virtual void Execute(T1 para)
{
(m_pObj->*m_pMemberFunc)(para);
}
private:
T* m_pObj;
void (T::*m_pMemberFunc)(T1);
};

template
class slot
{
public:
template
slot(T* pObj,void (T::*pMemberFunc)(T1))
{
m_pSlotbase=new slotimpl (pObj,pMemberFunc);
}
~slot()
{
delete m_pSlotbase;
}
void Execute(T1 para)
{
m_pSlotbase->Execute(para);
}
private:
slotbase * m_pSlotbase;
};

template
class signal
{
public:
template
void bind(T* pObj,void (T::*pMemberFunc)(T1 para))
{
m_slots.push_back(new slot (pObj,pMemberFunc));
}
~signal()
{
vector * >::iterator ite=m_slots.begin();
for (;ite!=m_slots.end();ite++)
{
delete *ite;
}
}
void operator()(T1 para)
{
vector * >::iterator ite=m_slots.begin();
for (;ite!=m_slots.end();ite++)
{
(*ite)->Execute(para);
}
}

private:
vector * > m_slots;
};

#define CONNECT(sender,signal,receiver,slot) sender.signal.bind(receiver,slot)

class receiver
{
public:
void callback1(int a)
{
cout<<"receiver1: "< }
};
class receiver2
{
public:
void callback2(int a)
{
cout<<"receiver2: "< }
};

class sender
{
public:
sender(): m_value(0) {}
int get_value()
{
return m_value;
}
void set_value(int new_value)
{
if (new_value!=m_value)
{
m_value=new_value;
m_valueChanged(new_value);
}
}
signal m_valueChanged;
private:
int m_value;

};

int main(int argc,char** arg)
{
receiver r;
receiver2 r2;
sender s;
CONNECT(s,m_valueChanged,
首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇UVA12716 GCD XOR 数论数学构造 下一篇UVA 10883 Supermean 上下取对数..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: