C++模板编程模式CTRP

来源:互联网 发布:怎么搜淘宝衣服好看 编辑:程序博客网 时间:2024/06/14 17:58

C++模板编程模式CTRP

CRTP ,curiously recurring template pattern 奇特的递归模板编程,意思是一个类继承的父类是个模板类,参数是自己。

// 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>{    // ...};

1. CRTP 可以用于实现静态多态性

不同于虚函数需要在函数运行时才能够确定真正被调用的函数是哪一个,通过CRTP手段可以让我们实现静态多态性,在编译期间就可以确定真正调用的函数类型。主要解决的是虚函数实现的多态效率低下的问题,继承层次多了,虚函数这种动态实现多态的机制效率低下,资源浪费严重。

#include <iostream>using namespace std;template<typename T>class BaseClass{public:    void Func()    {        //通过静态类型转换,调用对应类型的成员函数,实现静态多态性        static_cast<T*>(this)->funcImpl();    }private:     void funcImpl()    {        cout << "Base class" << endl;    }};class Base : public BaseClass<Base>{};class Derive : public BaseClass<Derive>{public:    void funcImpl()    {        cout << "Derive class" << endl;    }};int main(int argc, char* argv[]){    BaseClass<Derive> der;    der.Func();     //Derive class    BaseClass<Base> bas;    bas.Func();     //Base class    return 0;}

2. CRTP 可以用于定义一些公共的函数,然后子类继承,可以实现代码的复用性

如下是一个利用CRTP来实现单例模式。

#include <iostream>#include <memory>#include <Windows.h>using namespace std;// 互斥锁对象class Mutex{public:    Mutex();    ~Mutex();    void lock() const;    void unlock() const;private:    HANDLE m_hMutex;};//在构造函数里创建锁Mutex::Mutex(){    m_hMutex = ::CreateMutex(NULL, FALSE, NULL);}//析构函数里销毁锁Mutex::~Mutex(){    ::CloseHandle(m_hMutex);}//互斥锁上锁void Mutex::lock() const{    DWORD d = WaitForSingleObject(m_hMutex, INFINITE);}//互斥锁解锁void Mutex::unlock() const{    ::ReleaseMutex(m_hMutex);}template <class T>class CSingleton {public:    static T* Instance()            // 取单例对象    {        if (s_instance.get() == NULL)       // double check + 加锁 保证单例对象的创建唯一        {            mutex.lock();            if (s_instance.get() == NULL)            {                s_instance = shared_ptr<T>(new T);            }            mutex.unlock();        }        return s_instance.get();    }protected:                  // 构造函数和析构函数设定为protected可允许派生类访问    CSingleton() {}     ~CSingleton() {}private:                        //  拷贝构造函数和赋值运算符设定为private的,并且设定为delete或者声明并不实现。    CSingleton(const CSingleton<T>&) = delete;    CSingleton<T>&  operator=(const CSingleton<T> &) = delete;private:    static shared_ptr<T> s_instance;    static Mutex mutex;};// 初始化CSingleton<Foo>的静态成员变量class Foo;template<> shared_ptr<Foo> CSingleton<Foo>::s_instance;template<> Mutex CSingleton<Foo>::mutex;//初始化CSingleton<T>的静态成员变量//template<typename T> shared_ptr<T> CSingleton<T>::s_instance;//template<typename T> Mutex CSingleton<T>::mutex;//单例模式,基类使用的模型class Foo : public CSingleton<Foo>{    friend class CSingleton<Foo>;   // 基类可以调用自身定义的private构造函数private:    Foo() {}public:    void fun()    {        cout << "fun " << endl;    }    /*其他定义*/};int main(){    Foo* f = Foo::Instance();    f->fun();    cin.get();    return 0;}

3. 对象计数(Object counter),记录一个类被创建和销毁的次数,

#include <iostream>using namespace std;template <typename T>struct counter{public:    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 : public counter<X>{    // ...};class Y : public counter<Y>{    // ...};int main(){    X x;    cout << X::objects_created << endl;    return 0;}

能够对X和Y类分开计数,只能用模板实现,普通的继承基类无法实现。