文章目录
C++ CRTP 详解:奇异递归模板模式的原理与应用
在 C++ 编程中,模板不仅仅用于泛型编程,还可以发挥出“元编程”的威力。CRTP,即“奇异递归模板模式”,正是一种利用模板实现静态多态和代码复用的设计模式。本文将从原理、示例、优缺点以及新标准对其的改进等多个角度详细讲解 CRTP。
CRTP 简介
CRTP 的英文全称为 Curiously Recurring Template Pattern,顾名思义,就是让一个类在继承时将自身作为模板参数传给其基类。例如:
// 基类模板
template <typename Derived>
class Base {
public:
// 调用派生类的成员函数 implementation()
void interface() {
static_cast<Derived*>(this)->implementation();
}
// 如果派生类没有重写,基类可以提供一个默认实现
void implementation() {
// 默认行为
}
};
// 派生类,将自身作为模板参数传入基类
class Derived1 : public Base<Derived1> {
public:
void implementation() {
std::cout << "Derived1::implementation()" << std::endl;
}
};
上述代码中,Derived1
继承自 Base<Derived1>
,基类中通过 static_cast
将 this
转换为派生类指针,从而在调用 interface()
时能够调用到派生类重写后的 implementation()
方法。这种技术利用了 C++ 模板延迟实例化的特性,可以在编译期实现类似于多态的效果,而无需虚函数的运行时开销
CRTP 的原理与实现
静态多态
传统的多态通常依赖于虚函数(运行时多态),这需要为每个对象存储虚表指针并进行动态查找,虽然这种方式非常灵活,但也会带来一定的性能开销。相比之下,CRTP 实现的是静态多态,即在编译期就确定调用哪个函数,从而避免了虚函数的额外成本。
示例代码(静态多态):
#include <iostream>
using namespace std;
template <typename Derived>
class Shape {
public:
// 定义统一接口,调用派生类实现的 do_draw()
void draw() {
static_cast<Derived*>(