//单例模板
template <typename T>
class Singleton
{//使用默认构造和析构函数Singleton() = default;~Singleton() = default;
public://删除默认的移动、拷贝、赋值、取址Singleton(Singleton &&) = delete;Singleton(const Singleton &) = delete;void operator = (const Singleton &) = delete;T *operator &() = delete;static T* instance(){static T object;return &object;}
};
使用示例:
//测试类
class Test
{int id;
public:void setId(int id){this->id = id;}int getId() const{return this->id;}
};int main()
{Singleton<Test>::instance()->setId(5);std::cout << Singleton<Test>::instance()->getId() << std::endl;
}
如果使用的时候觉得调用太长,可以将其 #define 一下,如:
#define SingletonTest Singleton<Test>::instance()int main()
{SingletonTest->setId(5);std::cout << SingletonTest->getId() << std::endl;
}
到这里你可能会提出质疑,我们在此处并没有做到禁止创建 Test 用户类的对象,如果你有这样的需求,那请往下看
为了禁止擅自创建 Test(用户类对象),我们改变下策略:
放开模板限制,在此不再删除取址操作(会影响返回对象的引用),取消模板类构造函数的私有化,作为基类,析构函数标记为virtual;
//单例模式基类,CRTP模板
template <typename T>
class Singleton {
public:Singleton() = default;virtual ~Singleton() = default;Singleton(Singleton &&) = delete;Singleton(const Singleton &) = delete;void operator = (const Singleton &) = delete;static T* instance(){static T object;return &object;}
};
用户类继承单例模板
与之前不同的是,将创建对象的限制放在了用户类(即将构造函数设置为私有),构造函数私有化后,单例模板也无法创建对象,于是,将单例模板作为友元类, 模板类才能访问到用户类的构造函数
class Test : public Singleton<Test>
{
public:void setId(int id){this->id = id;}int getId() const{return this->id;}
private:int id;Test() = default;//单例模板作为友元类friend class Singleton<Test>;
};
使用示例:
int main()
{//Test t; //错误,禁止创建对象Test::instance()->setId(5);std::cout << Test::instance()->getId();
}