设计模式之单例模式
时间:2020-08-19 00:47:26
手机看文章
扫描二维码
随时随地手机看文章
[导读]程序喵最近开始系统学习回顾设计模式,希望能把学到的东西分享给大家,今天总结下创建型模式中最经典的单例模式。 “ 什 么 是 单 例 模 式 ? ” 这里首先介绍下什么是创建型模式,创建型模式主要解决对象的创建过程,封装对象复杂的创建过程,解耦对象
程序喵最近开始系统学习回顾设计模式,希望能把学到的东西分享给大家,今天总结下创建型模式中最经典的单例模式。
而单例模式指的就是在系统里一个类只能产生一个实例,确保全局唯一。
“
懒 汉 式 实 现 1
”
class Singleton {public:static Singleton *GetInstance();void Func() { std::cout << "Singleton Func \n"; }private:Singleton() {} // 避免外部构造对象,想拿到类的实例只能通过GetInstance()Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;static Singleton *instance_;static std::mutex mutex_;};Singleton *Singleton::instance_ = nullptr;std::mutex Singleton::mutex_;Singleton *Singleton::GetInstance() {// double checkif (instance_ == nullptr) { // 1std::unique_lock<std::mutex> lock(mutex_);if (instance_ == nullptr) { // 2instance_ = new Singleton();}}return instance_;}int main() {Singleton::GetInstance()->Func();return 0;}
为什么需要加锁?加锁的原因很简单,为了确保线程安全。
您看过代码可能也有些疑惑,明明加一次锁和第二次的判断就足够了,为什么在加锁之前还需要进行一次判断呢?这里可以考虑只需要在判断指针为空的时候才去加锁,避免每次调用方法时都加锁,可以减少加锁解锁带来的额外开销。
这里需要将类的构造函数和拷贝构造函数等设成私有函数,避免外部构造类的实例,防止外部通过new关键字进行实例化。
“
懒 汉 式 实 现 2
”
class Singleton {public:static Singleton& GetInstance() {static Singleton instance;return instance;}void Func() { std::cout << "Singleton Func \n"; }private:Singleton() {} // 避免外部构造对象,想拿到类的实例只能通过GetInstance()Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;};int main() {Singleton::GetInstance().Func();return 0;}
“
饿 汉 式 实 现
”
class Singleton {public:static Singleton *GetInstance();void Func() { std::cout << "Singleton Func \n"; }private:Singleton() {} // 避免外部构造对象,想拿到类的实例只能通过GetInstance()Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;static Singleton *instance_;};Singleton *Singleton::instance_ = new Singleton();Singleton *Singleton::GetInstance() {return instance_;}int main() {Singleton::GetInstance()->Func();return 0;}
“
std::call_once实现 ”
template <typename T>class SingleTon {public:static T& instance() {std::call_once(once_, &SingleTon::init);return *value_;}private:SingleTon();~SingleTon();SingleTon(const SingleTon&) = delete;SingleTon& operator=(const SingleTon&) = delete;static void init() { value_ = new T(); }static T* value_;static std::once_flag once_;};
总结
-
类只能有一个实例。 -
外部用户不能也无法自行对类进行实例化,实例化的操作需要类内部去实现。 -
整个进程共用一个类的实例,且需要是线程安全的。
往期推荐
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!





