CRTP (The Curiously Recurring Template Pattern) 是 C++ 模板中的一种习惯用法:子类继承时将自己作为基类的模板参数。
一般形式:
1
2
3
4
5
6
7
8
| template <typename T>
class Base {
};
class Derived: public Base<Derived> {
};
|
这样就能在基类访问子类的成员变量及函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| #include <iostream>
template <typename T>
class Base {
public:
void call() {
// 通过强制类型转换转换成子类指针并调用子类方法和成员
T* t = static_cast<T*>(this);
t->impl();
std::cout << "base : " << t->a << std::endl;
}
};
class DerivedA : public Base<DerivedA> {
public:
void impl() {
std::cout << "derived A" << std::endl;
}
int a = 10;
};
class DerivedB : public Base<DerivedB> {
public:
void impl() {
std::cout << "derived B" << std::endl;
}
int a = 20;
};
int main(int argc, char* argv[]) {
Base<DerivedA>* a = new DerivedA;
Base<DerivedB>* b = new DerivedB;
a->call();
b->call();
free(a);
free(b);
return 0;
}
|
1
2
3
4
| derived A
base : 10
derived B
base : 20
|
约束:Base 中调用的方法和成员必须在子类中实现,否则会出现编译错误
通过这种方式,可以实现编译期多态,日常使用中最常见到使用这种机制的就是 enable_shared_from_this 这个类。