[C++]实现委托模型
2015-02-04 09:35
225 查看
Function Pointers and the Fastest Possible C++ Delegates》中提出(原文地址:http://www.codeproject.com/KB/cpp/FastDelegate.aspx)。这个模型的特点就是“Fast”,因此不可避免地要依赖编译器的具体实现,虽然文章的最后说明该模型已在大部分的编译器上通过了测试,我仍然对此不太放心,要是哪个编译器升级后改变了实现方式,这个模型就不适合使用了。而且,由于自身水平有限以及懒惰的心理,我也不想去深究每种编译器的具体实现方式。我想要的是符合C++标准,与编译器无关的模型,而不管它是否“Fast”。经过不断的摸索,终于写出了这样的一个委托模型,下面与大家分享一下该模型的实现原理。(当然,如果你认为FastDelegate已经满足需求,而且不担心它依赖于编译器,那么完全可以忽略本文)
成员函数指针的操作
在开始之前首先介绍一下成员函数指针,它与非成员函数指针的操作方式有很大的不同。有这么一个类:
那么如何通过成员函数指针来调用该函数呢?成员函数都有一个隐含的this参数,表示函数要操作的对象,现在我们只获取到了函数的指针,还缺少一个对象作为this参数。为了达到这个目的,需要先创建一个对象,然后通过该对象来调用成员函数指针:
第一步:使用类模板
通过上面的介绍,我们知道了要调用一个成员函数,仅仅有成员函数指针是不够的,还需要一个对象指针,所以要用一个类将两者绑到一起。由于对象的类型是无穷多的,所以这里必须使用类模板:
第二步:使用多态
对于单目标的委托来说,使用上面的代码或许就已经足够了。但是我的目的当然不止于此,我想要的是多目标的委托。多目标委托其实就是一个容器,在这个容器里可以存放多个对象,当调用委托的时候依次调用每个对象。容器里的对象应该都是相同的类型,这样才能够放到强类型的容器中;而且委托调用方不应该知道具体的调用目标是什么,所以这些对象也应该要隐藏具体的细节。遗憾的是,上一步中实现的类模板都不具备这些能力,DelegateHandler<A>和DelegateHandler<B>是不同的类型,不能放到同一个容器中,调用方要调用它们也必须知道调用的目标是什么类型。
解决这个问题的方法就是使用多态,令所有的委托目标类都继承一个公共的接口,调用方只通过这个接口来进行调用,这样就不必知道每个目标具体的类型。下面就是该接口的定义:
不知道你注意到没有,上面写了那么多代码,只是为了实现一个返回值为void,有一个int参数的委托!如果要实现更多类型的委托,上面的代码就要重复很多次了。幸好,C++有宏这个东西,使用它可以帮助我们快速生成大量代码。然而这个宏的定义可不是那么简单,为了它我费了好大周折。下面开始讲述这个探索的过程,如果不想看我啰嗦,可以直接跳到后面看现成的代码。
我们都知道,函数参数的声明可以只有类型而没有名称,但是为了在函数内使用参数,该参数必须有名称。例如:
既然如此,我们就使用两个__VA_ARGS__,一个用于函数参数的声明,一个用于调用。以上面的为例,第一个__VA_ARGS__应该是这样子:
相关文章推荐
- [C++]实现委托模型
- [C++]实现委托模型
- [C++]实现委托模型
- [C++]实现委托模型
- 【转】[C++]实现委托模型
- [C++]实现委托模型
- [C++]实现委托模型
- 模版函数指针,C++委托的实现
- C++中实现.NET风格的委托(经典收藏)
- 由C++到C#:委托模型
- 深入理解C++对象模型-成员函数的本质以及虚函数的实现(非虚继承)
- 在你的C++程序里实现委托 (转)
- 两个c++编译器对c++对象模型和虚函数调用方式的实现
- 在你的C++程序里实现委托
- 模版函数指针,C++委托的实现
- 用C++实现C#中的委托和事件
- 在你的C++程序里实现委托
- 在C++中用虚函数及模版实现委托(支持多播)
- 用C++模板实现事件模型
- C++ GUI Programming with Qt 4 - 10.3 实现自定义模型