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> { // ... };
目的是啥呢?主要解決的是虛函數實現的多態效率低下的問題,繼承層次多了,虛函數這種動態實現多態的機制效率低下,資源浪費嚴重。this
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",模擬的動態綁定。指針
傳統的多態是這樣的,使用基類指針指向實例化後的子類,經過虛函數實現多態。code
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)上代碼:ip
// 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_patternrem