为便于编写不同派生类的单例模式(不同派生类的构造函数具有不相同的参数数目),故基于一般CRTP单例模式,编写了如下不定参数的CRTP单例模式。
如下为头文件。
// crtp.h
#include<memory>
#include<mutex>
template<class Derived>
class Singleton{
public:
template<class ...Args>
static Derived& get_Instance(const Args& ...args);
protected:
Singleton()=default;
~Singleton()=default;
private:
Singleton(Singleton&) =delete;
static std::unique_ptr<Derived> _Instance;
static std::once_flag _flag;
};
class derivedA:public Singleton<derivedA>
{
private:
int p;
friend class Singleton<derivedA>;
derivedA(int);
public:
int get_val() const;
~derivedA()=default;
};
class derivedB:public Singleton<derivedB>
{
private:
int p,q;
friend class Singleton<derivedB>;
derivedB(int,int);
public:
std::pair<int,int> get_val() const;
~derivedB()=default;
};
如下为实现。
#include "crtp.h"
template<class Derived>
template<class ...Args>
Derived& Singleton<Derived>::get_Instance(const Args& ...args){
std::call_once(_flag,[](auto ...args){
_Instance.reset(new Derived(args...));
},args...);
return *_Instance;
}
template<class Derived>
std::unique_ptr<Derived> Singleton<Derived>::_Instance=nullptr;
template<class Derived>
std::once_flag Singleton<Derived>::_flag;
derivedA::derivedA(int _val): p(_val)
{
}
int derivedA::get_val() const {return p;}
derivedB::derivedB(int _val1,int _val2): p(_val1),q(_val2)
{
}
std::pair<int,int> derivedB::get_val() const {return {p,q};}
int main(){
derivedA& dA=derivedA::get_Instance(2);
derivedB& dB=derivedB::get_Instance(2,3);
return 0;
}