CRTP (Curiously Recurring Template Pattern) 奇异递归模板模式- 编译期多态是一种C++模板编程技术,用于实现编译期多态(静态多态),与运行时多态(通过虚函数实现)形成对比。
#### 1、CRTP的核心思想是:
一个类派生自一个以自身为模板参数的模板基类。
```
template <typename Derived>
class Base {
// ...
};
class Derived : public Base<Derived> {
// ...
};
```
#### 2、工作原理
1. 模板基类:接受派生类类型作为模板参数
2. 派生类:继承自以自身为模板参数的基类
3. 静态多态:通过静态转换实现方法调用,无需虚函数开销
#### 3、典型应用场景
- 静态多态(编译期多态)
```
template <typename Derived>
class Animal {
public:
void speak() {
static_cast<Derived*>(this)->speakImpl();
}
};
class Dog : public Animal<Dog> {
public:
void speakImpl() {
std::cout << "Woof!" << std::endl;
}
};
class Cat : public Animal<Cat> {
public:
void speakImpl() {
std::cout << "Meow!" << std::endl;
}
};
```
- 对象计数器
```
template <typename T>
class Counter {
static int count;
public:
Counter() { ++count; }
~Counter() { --count; }
static int getCount() { return count; }
};
template <typename T>
int Counter<T>::count = 0;
class Widget : public Counter<Widget> {
// ...
};
```
- 链式调用
```
template <typename Derived>
class Chainable {
public:
Derived& setX(int x) {
static_cast<Derived*>(this)->x = x;
return static_cast<Derived>(this);
}
Derived& setY(int y) {
static_cast<Derived*>(this)->y = y;
return static_cast<Derived>(this);
}
};
class Point : public Chainable<Point> {
public:
int x, y;
};
// 使用
Point p;
p.setX(10).setY(20);
```
#### 4、优点
1. 无虚函数开销:避免了虚函数调用的运行时开销
2. 编译期绑定:所有方法调用在编译期确定
3. 更好的性能:适合性能敏感的场景
4. 更灵活的设计:可以在编译期实现多态