[C++模板技术] 线性继承体系自动生成
来源:互联网 发布:java中遍历数组 编辑:程序博客网 时间:2024/05/21 10:36
散乱的继承体系,或者说多重继承可能不是我们所需要的,尤其是当继承链中的基类中含有虚函数时,其可能会不可避免的造成为了维护虚函数表而产生的额外负担。除之外,很多我们的设计本身可能与多重继承不是很适配,因此,我们需要一个类似的,但是能够生成线性继承链的技法。
首先,假设我们有一个事件处理接口类:
template <typename T>class EventHandler{public:virtual void OnEvent(const T&, int EventID) = 0;virtual ~EventHandler() = default;};我们可以利用前文提到的散乱继承体系生成器生成一个处理所有图形事件的接口:
using WidgetEventHandler = GenScatterHierarchy<TYPELIST_3(Window, Button, ScrollBar),EventHandler>;但是需要注意的是,这样生成的接口类实际上是对于三个具有虚函数的基类的多重继承,针对每一个基类的部分,因为其含有虚函数,因此都需要维护一个虚函数表指针,在这里,一共就造成了3个虚表指针的额外负担,这显然不是我们想要的。为了解决这个问题,如果我们生成的继承体系是线性的。那么无论继承了多少个基类,我们都可以只用维护一个虚表指针了,这里,我们引入GenLinearHierarchy模板类:
template<typename TList,template <typename AtomicType, typename Base> class Unit,typename Root = EmptyType>class GenLinearHierarchy;上述模板类是生成器的母版,为了能够完成线性递归继承,和散乱继承生成器不同,我们需要让模板类Unit额外提供一个基类参数,这个基类参数代表的是Unit模板类实例化后所继承的父类类型,在最终实例化后的继承体系中,每一个Unit实例的父类都将是一个GenLinearHierarchy实例,而最顶端的Unit实例的基类,也就是整个继承链的顶端基类,作为递归终点,我们利用Root参数来指定,默认的,Root类型为EmptyType,EmptyType具体构造与之前文章中的NullType实作方式相同,只是一个空结构体。
接着,我们提供一般的递归过程,偏特化这个类:
template<typename T1,typename T2,template <typename,typename> class Unit,typename Root>class GenLinearHierarchy<TypeList<T1,T2>,Unit,Root>:public Unit<T1,GenLinearHierarchy<T2,Unit,Root>>{};接着,我们针对递归出口提供一个偏特化:
template<typename T,template <typename,typename> class Unit,typename Root>class GenLinearHierarchy<TypeList<T,NullType>, Unit, Root>:public Unit<T,Root>{};以上就是全部内容了,我们可以比较一下两种生成器生成的接口的大小:
template <typename T>class EventHandler1{public:virtual void OnEvent(const T&, int EventID) = 0;virtual ~EventHandler1() = default;};template <typename T,typename Base>class EventHandler2:public Base{public:virtual void OnEvent(const T&, int EventID) = 0;virtual ~EventHandler2() = default;};using WidgetEventHandler1 = GenScatterHierarchy<TYPELIST_3(Window, Button, ScrollBar),EventHandler1>;using WidgetEventHandler2 = GenLinearHierarchy<TYPELIST_3(Window, Button, ScrollBar),EventHandler2>;int main(){// Test on VS2015cout << sizeof(WidgetEventHandler1) << endl; // 12 cout << sizeof(WidgetEventHandler2) << endl; // 4return 0;}可以看出,采取多重继承的方式,我们需要维护3个虚表指针,sizeof后输出12,而采用线性继承的方式,我们只需要维护一个虚表指针,sizeof的结果是4。
阅读全文
0 0
- [C++模板技术] 线性继承体系自动生成
- [C++模板技术] 散乱继承体系自动生成
- shell脚本自动生成C文件模板
- 【架构技术】模板类继承
- eclipse 自动生成注释模板
- freemarker自动生成代码模板
- 继承体系
- 继承体系
- [C#]一步一步开发自己的自动代码生成工具之五:DAL层模板
- [C#]一步一步开发自己的自动代码生成工具之六:业务层模板
- eclipse develop for C\C++ 文件注释函数注释代码模板自动生成方法
- Python之自动生成代码继承关系
- 技术体系
- 生成高斯模板(C++)
- 生成高斯模板(C++)
- c语言 线性表的生成代码
- 自动按模板生成网站首页.
- 自动按模板生成网站首页
- POJ 1236 Network of Schools (tarjan求强连通,缩点)
- [深度学习论文笔记][arxiv 1702]Understanding Convolution for Semantic Segmentation
- banner图片
- Keras指定使用GPU
- postgresql~*符号的含义
- [C++模板技术] 线性继承体系自动生成
- FZU 2231 平行四边形数 (组合计数)
- 开学第一天学习练习
- 自定义TopBar
- mysql基础(二)
- mybatis入门之Helloworld
- 实现图片的拖拽缩放功能
- Sublime Text编辑器如何显示顶部的菜单栏
- Android开发对网络缓存的理解