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类分开计数,只能用模板实现,普通的继承基类无法实现。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/70529.html