一种C++设计模式的介绍。
C++
类、继承、多态、虚函数、虚指针、重载和重写
在语言标准的层面,C++提供动态多态实现是基于virtual-Function、v-ptr以及v-table的。但这种方法,我们需要额外占用内存空间维护虚表,并且,在每次调用虚函数时,会增加在虚表中查找对应函数时间的消耗。这种消耗在常规的程序中,其实也还好;但在一些对性能要求极高的场景,有代码洁癖追求极致性能的人可能就不会这样使用,会绕过虚函数来实现多态,当然有得有失,提高了速度,就要付出某些代价。这就是本文所要讲解的CRTP。
CuriouslyRecurringTemplatePattern,CRTP很多人翻译成奇异递归模板模式,但我觉得这样的翻译怪怪的,还是觉得从英文理解比较好一点。
Curiously古怪的,奇怪的,好奇的。
CuriouslyRecurringTemplatePattern奇怪的重复模板模式
这种奇怪来自于定义上:
templateclassTstructBase{voidimplementation(){//...static_castT*(this)-implementation();//...}};structDerived:BaseDerived{voidimplementation();};
structDerived:BaseDerived是CRTP最明显的特征和最难以理解的部分,即Derived派生自Base,但用Derived自己来特化Base。
这种语法似乎有点不可思议,逛了一圈中文blog,大部分都是告诉你该怎么做,但并没有人告诉你为什么这样是对的,理解起来还是很别扭,去外网逛了逛,突然顿悟了??,进行记录。在C++加持了Template语法黑魔法的世界里,这样的语法确实能够通过编译器,甚至能够绕过虚函数来实现多态机制。理解这一点,我们可能需要两个知识点的铺垫。
一
我们知道,C/C++是强类型的语言,但有没有想过,类型到底是什么呢?C++中类型系统极其庞大和复杂,有内置定义的类型,有用户自定义的类型(class、struct,enum......),或者说,我们用类型定义一个变量,编译器为我们做了什么事情呢?
inti;
我觉得在C++中,类型最大的作用就是确定变量关联的内存大小。int代表i是4个字节(均只考虑一般情况下),double是8个字节。当然C++也给你一些方法可以绕过类型系统。但类型就是要确定这个变量所要申请空间的大小,至少对于C++来说,如果我们不知道类型大小的话,是无法申请对应的变量的。
Ref.如何绕过C++类型系统