Delegate

delegate有很多种实现,常见的通用库就不说了,说说我在游戏库里我见得比较有代表性的三个。

 

设计一个delegate我觉得主要有两个问题,一个是模版参数的设计,一个是绑定方法时间的设计。拿来对比的有三个,Hikari的FastDelegate,CEGUI的slot,Nebula3的Delegate。。。必须说这三个太好玩了。。。设计上想法相似度基本=0,对我帮助大大滴。首先说模版参数设计,我最早写的delegate的模版参数有两个,一个是RetType,一个ArgType,用多了就发现一个纠结的问题,RetType是个累赘,为什么呢?delegate本来就把成员函数包装成了个类C的函数,那RetType很可能是void,但是实现的时候,如果RetType为void,那模版编译就不通过了。。。很明显,把RetType放到ArgType是最合理的。Hikari就是这么做的,FastDelegate2,参数有两个,虽然没有明确指出参数作用,但是很明显可以想到,一个很可能是返回值,一个是参数。但这其实只是把问题换了个地方,解决问题的的方式看起来好看了些,不会出现编译错误。我觉得用delegate就像是在用脚本,是两个东西见联系的纽带,而封装脚本的方式,一般参数是一个灵活的结构体,所以我觉得这样比较合理。N3就是用的这种思路。不过话说回来,N3和Hirkari的解决方法虽然实现起来很简单,但是想明白用的舒服,缺着实费了我半天功夫,如果懒得想,那就简单的办法就是CEGUI那样,用啥写啥,写死到里面,当然可以稍微让CEGUI的代码好看一些,把参数模版化,也是一个完整的解决办法,但是悲剧在于CEGUI为了实现freefunction和membermethod使用了虚函数,虽然虚函数没什么大碍,但是有跟快的方法为啥不用呢。N3的方法是模版编译的时候确定被调用的方法,生成不同的调用函数。Hikari则用了一些比较飘逸的方法,复杂了许多,好处就是绑定的时候参数就是fuction,看着舒服也好理解。而N3的delegate我曾经质疑了半天他的应用范围,就是因为创建delegate的函数需要带有函数作为模版参数。这就想到了第二个问题,何时绑定。

 

模版是在编译期生成的,这个都知道。但是这个问题我很少去仔细琢磨。遇到这个问题后好好想了一把。如果用函数做参数,相当于我们在编译期告诉了编译器,我们需要的是函数表中的一个地址。用函数做模版参数也是一样的。而这个函数表中的地址,是不会改变的,它不是个对象,不会消除。所以编译期可以确定,在这点上看,它俩是等价的。但是貌似看来,使用函数作为参数绑定貌似对程序来说更为灵活,我们可以在运行期在绑定函数,但是真的可以么?可以。。。恩。。。我必须承认,通过用一些淫荡的办法读取函数表,取函数绝对地址当然可以,但是这依赖于编译期,我们不知道哪天我们的程序编译结果就是错的了。而且我想也没有人会去这么做。所以,这点点微不足道的优势,我觉得可以忽略。

 

最后总结一下。。。N3的这个delegate太棒了。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值