C++ 虚拟函数vs 回调函数 像有虚拟方法表一样有一个虚拟变量表就可以实现类级回调函数了
虚拟函数使得对象用同一个名字,调用不同函数.
这种多态实现了某种概念的抽象.
用回调也可以达到类似的效果,某种意义上,用回调更灵活.
由于C++的类回调函数的强类型导致用起来不够灵活方便,
这里的回调函数可以用Delegate代替.
其实用回调是典型的使用聚合而不使用继承的思路.
最典型的例子就是Thread类,
通常的做法是写一个非虚拟的Run,调用虚拟的Excute.
用到Thread的地方,继承Thread实现Excute即可.
而用回调的方式,只需设置回调即可,不用新建一个类来继承.
尤其当用到的Thread较多时,避免了类的数目的膨胀.
针对接口编程,经常声明一个接口类,
一方拥有这个接口,使用这个接口,另一方从这个接口继承,实现接口.
如果采用Delegate的方法,有时可以省去单独的接口类.
虚拟函数的问题在于其同时实现了接口继承和实现继承.
而回调函数可以看作接口继承,因此更灵活.
虚拟方法表由编译器自动处理,回调函数由人工管理.
但是,虚拟函数基于类,同一个类的对象共享一个虚拟方法表,
而回调函数却是基于对象的,每个对象都有一个回调函数指针.
能否让对象共享同一个回调函数指针?
类可以共享静态变量,但类和子类也共享该静态变量.
(单例模式不能继承就面临的这个问题,用模板实现编译时多态).
那么除非根据函数名结合类名查表,调用不同函数.
如果语言支持与子类独立的类级共享变量,
也就是说在父类声明一个类级变量,子类中也有一个同名的类级变量.这两个变量同名但独立.
就像虚拟方法表一样有一个虚拟变量表就好了.
这样就可以实现前面的基于类的回调函数.
语言不直接支持,我们只有diy了
//ClassVariable代表类共享变量.
//ClassVariable中主要存放的是类级回调函数,或者说Deletegate.
struct ClassVariable
{
};
//每个类都声明一个同名的静态成员变量ClassVar;
class TObject
{static ClassVariable* ClassVar;
virtual ClassVariable* GetClassVariable(){return ClassVar};
每个类从父类继承并扩展相应的ClassVariable结构.
那么如何实现多态呢?
在一个非虚拟函数里,调用ClassVar所指向的一个运行时设定的Deletegate.
使用ClassVar前
借鉴QT中的RTTI的相关思路.
提供一个函数,进行类型转换,将通用的ClassVariable,
转换为与类相关的特定类型的指针.
某种意义上RTTI信息就是类的共享的数据.
可以研究下C++的Rtti,以及类库的Rtti的实现原理.
如果C++直接支持delegate,虚拟变量表,消息机制就好了