CRTP
方式:父类是模板,然后定义一个子类继承它,并且模板参数是子类。
1 2 3 4
| template<class Dervied> class Base {};
class X : public Base<X> {};
|
CRTP作用
CRTP可用于在父类暴露接口,而子类实现该接口,以此实现”编译期多态(静态多态)”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| template <class Dervied> class Base { public: void addWater(){ static_cast<Dervied*>(this)->impl(); } };
class X : public Base<X> { friend class Base<X>; private: void impl() const{ std::cout<< "X 设备加了 50 毫升水\n"; } };
|
其中,static_cast<Dervied*>(this)将父类指针转化为子类指针而调用子类的方法。
这个转换是安全合法的。因为 this 指针实际上指向一个 X 类型的对象,X 类型对象继承了 Base<X> 的部分,X 对象也就包含了 Base<X> 的部分,所以这个转换在编译期是有效的,并且是合法的。
CRTP实现单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| template<class T> class Singleton{ public: static T& GetInstance(){ static T ins; return ins; } protected: Singleton() = default; virtual ~Singleton(){}; Singleton(const Singleton<T> &) = delete; Singleton<T>& operator=(const Singleton&) = delete };
class A : public Singleton<A>{ friend class Singleton<A>; private: A(){}; };
|