CRTP 奇异递归模板
**CRTP (奇异递归模板)**能以一种小于虚函数开销的方式来实现多态,但是这种多态是静态多态Static Ploymorphism
,就是类型的确定时发生在编译期的,这种写法能减小虚函数的性能开销,但是他的缺陷是不适用于哪些运行时的多态,即类型是在运行时才能确定的情况是不适用于静态多态的。
比如如下一段代码
#include <iostream>
using namespace std;
struct Animal{
virtual void i_am_who() = 0;
};
struct Cat: public Animal{
void i_am_who() override{
cout<<"I am cat! miao miao~"<<endl;
}
};
struct Dog: public Animal{
void i_am_who() override{
cout<<"I am dog! wang wang~"<<endl;
}
};
int main(){
Animal* cat = new Cat;
Animal* dog = new Dog;
cat->i_am_who();
dog->i_am_who();
}
这就是一个简单的利用虚函数来实现多态,这种多态的实现是利用在RTTI
和虚表
来进行具体函数的跳转,是一种运行时的动态多态Dynamic Polymorphism
优点很明显,能封装具体的类型,通过一个统一的接口而调用不同方法,但是实现虚函数需要的性能开销相比于普通函数,往往是普通函数的几倍。而对于静态多态,即类型在编译器就可以确定的,可以利用CRTP
来实现静态多态,达到上面的目的,并且其性能开销也很小,跟普通函数性能相仿
#include <iostream>
using namespace std;
template<class specific_animal>
struct Animal{
void i_am_who(){
static_cast<specific_animal&>(*this).i_am_who();
}
};
struct Cat: public Animal<Cat>{
void i_am_who(){
cout<<"I am cat! miao miao~"<<endl;
}
};
struct Dog: public Animal<Dog>{
void i_am_who(){
cout<<"I am dog! wang wang~"<<endl;
}
};
int main(){
Animal<Cat>* cat = new Cat();
Animal<Dog>* dog = new Dog();
cat->i_am_who();
dog->i_am_who();
}