侯捷(设计模式总结)

1 Singleton单例 Singleton 是设计模式的一种,其特点是只提供唯一一个类的实例,具有全局变量的特点,在任何位置都可以通过接口获取到那个唯一实例;具体运用场景如:设备管理器,系统中可能有多个设备,但是只有一个设备管理器,用于管理设备驱动;数据池,用来缓存数据的数据结构,需要在一处写,多处读取或者多处写,多处读取;基础要点全局只有一个实例:static 特性,同时禁止用户自己声明并定义实例(把构造函数设为 private)线程安全禁止赋值和拷贝用户通过接口获取实
摘要由CSDN通过智能技术生成

1 Singleton

  • 单例 Singleton 是设计模式的一种,其特点是只提供唯一一个类的实例,具有全局变量的特点,在任何位置都可以通过接口获取到那个唯一实例;
  • 具体运用场景如:
  1. 设备管理器,系统中可能有多个设备,但是只有一个设备管理器,用于管理设备驱动;
  2. 数据池,用来缓存数据的数据结构,需要在一处写,多处读取或者多处写,多处读取;
  • 基础要点
  1. 全局只有一个实例:static 特性,同时禁止用户自己声明并定义实例(把构造函数设为 private)
  2. 线程安全
  3. 禁止赋值和拷贝
  4. 用户通过接口获取实例:使用 static 类成员函

1.1 有缺陷的懒汉式

  • 线程安全的问题,当多线程获取单例时有可能引发竞态条件:第一个线程在if中判断 m_instance_ptr是空的,于是开始实例化单例;同时第2个线程也尝试获取单例,这个时候判断m_instance_ptr还是空的,于是也开始实例化单例;这样就会实例化出两个对象,这就是线程安全问题的由来; 解决办法:加锁
  • 内存泄漏. 注意到类中只负责new出对象,却没有负责delete对象,因此只有构造函数被调用,析构函数却没有被调用;因此会导致内存泄漏。解决办法: 使用共享指针;
class Singleton
{
   
public:
    ~Singleton() {
   
        cout<<"destructor called!"<< endl;
    }
    static Singleton* get_instance()
    {
    if(m_instance_ptr == nullptr)
        {
   
            m_instance_ptr = new Singleton; 
        } 
        return m_instance_ptr;
    }
    void use() const{
    cout << "in use" << endl; }  
private:
    Singleton() {
   
        cout << "constructor called!" << endl;
    }
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;//=delete
    static Singleton* m_instance_ptr;
};
Singleton* Singleton::m_instance_ptr = nullptr;//静态成员类外定义,分配内存

1.2 线程安全、内存安全的懒汉式单例(智能指针,锁)

class Singleton
{
   
    typedef shared_ptr<Singleton> Ptr;
private:
    Singleton()
    {
   
        cout << "constructor called!" << endl;
    }
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    static Ptr m_instance_ptr;
    static mutex m_mutex;
public:
    ~Singleton()
    {
   
        cout << "destructor called!" << endl;
    }
    static Ptr get_instance()
    {
   
        if(m_instance_ptr == nullptr)//double lock
        {
   
            lock_guard<mutex>lk(m_mutex);
            if(m_instance_ptr == nullptr)
            {
   
               m_instance_ptr = shared_ptr<Singleton>(new Singleton);
            }
        }
        return m_instance_ptr;
    }
    void use() const
    {
   
        cout << "in use!" << endl;
    }
};
Singleton::Ptr Singleton::m_instance_ptr = nullptr;
mutex Singleton::m_mutex;

1.3 最推荐的懒汉式单例(magic static)局部静态变量

class 
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值