奇异递归模板模式 CRTP
CRTP 的用途
CRTP (Curiously Recurring Template Pattern) 主要用于实现静态多态。与 C++ 中常见的虚函数(virtual function)实现的动态多态不同,CRTP 在编译时解析函数调用,因此没有运行时开销。
举例
假设我们想创建一个通用的基类,它可以计算任何派生类的面积,只要派生类提供一个 getArea()
方法。
例子:计算几何图形的面积
首先,我们定义一个CRTP基类模板 Shape
。这个基类有一个方法 calculateAndPrintArea()
,它的任务是调用派生类中实现的 getArea()
方法,并打印结果。
1 |
|
接下来,我们创建两个具体的派生类:Circle
和 Rectangle
。它们都继承自 Shape
,并以自己作为模板参数。
1 | class Circle : public Shape<Circle> { |
如何使用
在 main
函数中,我们可以创建 Circle
和 Rectangle
对象,并直接调用基类中定义的 calculateAndPrintArea()
方法。
1 | int main() { |
为什么这个例子体现了 CRTP?
在这个例子中,Shape
基类模板利用奇异递归模板模式实现了静态多态。
静态类型信息:当
Circle
继承Shape<Circle>
时,Shape
类在编译时就知道了它所操作的对象类型是Circle
。静态绑定:在
Shape::calculateAndPrintArea()
方法中,static_cast<const Derived&>(*this)
将Shape
对象的引用转换为一个编译时已知的派生类引用。无运行时开销:
derived.getArea()
的调用是一个普通的函数调用,而不是虚函数表查找。这使得代码在运行时更加高效。
通过这个模式,我们为所有派生类提供了通用的接口 (calculateAndPrintArea()
),同时将具体实现 (getArea()
) 留给每个派生类自己完成,所有这些都在编译时完成,没有任何运行时多态的开销。