CRTP ,curiously recurring template pattern 神奇的复发模板范式,recurring实在不好翻译,没有合适的词汇,意思是继承的父类是个模板类,参数是自己。上代码看一下吧:
// The Curiously Recurring Template Pattern (CRTP)
template<class T>
class Base
{
// methods within Base can use template to access members of Derived
};
class Derived : public Base<Derived>
{
// ...
};
目的是啥呢?主要解决的是虚函数实现的多态效率低下的问题,继承层次多了,虚函数这种动态实现多态的机制效率低下,资源浪费严重。
CRTP用法一,实现静态多态(Static polymorphism),上代码:
template <class Derived>
struct base
{
void interface()
{
// ...
static_cast<Derived*>(this)->implementation();
// ...
}
};
struct derived : base<derived>
{
void implementation()
{
// ...
}
};
模板带来的好处是,只有Base<Derived>::implementation()使用时,静态函数才实例出来。这种用法有时被称为"simulated dynamic binding",模拟的动态绑定。
传统的多态是这样的,使用基类指针指向实例化后的子类,通过虚函数实现多态。
class Base
{
public:
virtual void method() { std::cout << "Base"; }
virtual ~Base() {}
};
class Derived : public Base
{
public:
virtual void method() { std::cout << "Derived"; }
};
int main()
{
Base *pBase = new Derived;
pBase->method(); //outputs "Derived"
delete pBase;
return 0;
}
CRTP用法二,对象计数(Object counter),记录一个类被创建和销毁的次数,上代码:
template <typename T>
struct counter
{
static int objects_created;
static int objects_alive;
counter()
{
++objects_created;
++objects_alive;
}
counter(const counter&)
{
++objects_created;
++objects_alive;
}
protected:
~counter() // objects should never be removed through pointers of this type
{
--objects_alive;
}
};
template <typename T> int counter<T>::objects_created( 0 );
template <typename T> int counter<T>::objects_alive( 0 );
class X : counter<X>
{
// ...
};
class Y : counter<Y>
{
// ...
};
能够对X和Y类分开计数,只能用模板实现,普通的继承基类无法实现。
CRTP用法三,多态拷贝构造(Polymorphic copy construction)上代码:
// Base class has a pure virtual function for cloning
class Shape {
public:
virtual ~Shape() {};
virtual Shape *clone() const = 0;
};
// This CRTP class implements clone() for Derived
template <typename Derived>
class Shape_CRTP : public Shape {
public:
virtual Shape *clone() const {
return new Derived(static_cast<Derived const&>(*this));
}
};
// Nice macro which ensures correct CRTP usage
#define Derive_Shape_CRTP(Type) class Type: public Shape_CRTP<Type>
// Every derived class inherits from Shape_CRTP instead of Shape
Derive_Shape_CRTP(Square) {};
Derive_Shape_CRTP(Circle) {};
传统的实现方式是,基类有个虚拟clone函数,每个继承类实现自己的clone函数功能。依靠CRTP技术,只定义一个就够了,大家通用。
资料来源:https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern