[cpp] (no subject)
lijie
cpunion at gmail.com
Tue Sep 5 11:52:03 CST 2006
至少有3种做法,其一是你这种想法,优点大概是使用简便。缺点也有,比如派生类的类型如果不用泛型方法则无法获知,如果不获取这个类型,使用reinterpret_cast在多继承时会遇到问题,想想下面这种情况:
class myDlg: public Serializable, public DlgBase{...};
如果能避免就没问题。或者像MFC的消息映射那样,不过看来不大适合你这里的构想。
其二是当然是运行期多态,问题在于它跟类型及方法都绑定得太紧了,你的button的事件方法跟一个对话框类绑定,会不会感觉太不舒服了?或许考虑一个Listener类,其它类从它上面派生。对话框类可能要写成:
class myDlg: public Listener, public DlgBase{
virtual void onEvent(...){...};
};
这就有上面说的那个问题,方法绑定太紧了,如果有多个button事件需要让myDlg来处理怎么办?
我觉得相对完美的方案是应该是委托,委托可以解除类型、对象、方法的绑定,它只需要调用接口一致。委托的方案大致是这样的:
class Button{
public:
Delegate<void()> onClick;
Delegate<void()> onDblClick;
};
class myDlg{
Button button;
EvnetLog clickLog;
EventLog dblClickLog;
public:
myDlg(){
clickLog.init("Button click");
dblClickLog.init("Button Double click");
button.onClick.bind(this, &myDlg::onButtonClick);
button.onClick.bind(&clickLog, &EventLog::logEvent);
button.onDblClick.bind(this, &myDlg::onButtonDblClick);
button.onClick.bind(&dblClickLog, &EventLog::logEvent);
}
};
这里演示了一个事件绑定多个观察者。
可以参考"成员函数指针与高性能的C++委托"一文,这篇文章引用得比较乱,不知道原作者是谁,网上搜索一下就有很多。这个委托好像只能绑定一个方法。Boost.Signals和libsigc++好像也有类似的东西,没仔细看过,只是以前。以前我也写过一个,不过没考虑效率,可能性能比较差劲,其它方面比如对象生存期管理也没完善,也没有进行广泛地测试,算是个学习模板时写的玩具,只在一个小项目里面用过:
http://www.cnblogs.com/cpunion/archive/2005/07/25/199800.html
jfwan网友(wanjunfeng)也写过一个,包括对象生存期管理,可以委托一个new出来的对象方法,在委托析构时会析构这个对象。不过他的blog上好像找不到这篇了。
这里列出的只是我知道的,可能还有很多实现。
在 06-9-4,Arcane<xjin at eta.com.cn> 写道:
>
> 大家好:
> 最近遇到一个问题,想请大家帮忙。
>
> 我想用一个类函数做为某个控件的回掉函数,如:
>
> class button;
>
> class DlgBase {};
> class myDlg : public DlgBase {
> public:
> void ButtonCB();
> button btn;
> }
>
> 现在的问题是,我想用ButtonCB() 作为btn的回掉函数。就是btn.callback(myDlg::ButtonCB);
>
> 我想知道callback的参数类型应该是什么?
> 虽然,这个例子里面,可以用:
> typedef void (myDlg::*CB)();
> 而callback的参数类型就是CB,
> 但是,问题是myDlg是用户定义的,button是我定义的,我不知道用户会定义出何种DlgBase的派生类,
> 那么,我的callback的参数类型应该怎么设置?
>
> 谢谢
> Arcane
More information about the Cpp
mailing list