单例模式--含义是在某一个类,在一个进程中只有唯一的一个对象

单例模式表示的含义是在某一个类,在一个进程中只有唯一的一个对象

并且在语法角度上进行制约
单例模式是一种设计模式,设计模式可以理解为经典问题场景下的经典解决方案。


(方案一)简易版本 对象定义后数据立即加载到内存
(饿汉模式)


(方案二)对象定义出来 先不着急加载到内存,等到第一次使用的时候,再将数据加载到内存
(懒汉模式)

饿汉模式

#include <stdio.h>
#include <iostream>
using namespace std;

template <class T>
//类模板
class Singleton_1
{
public:
    static T *GetInstance()//静态的成员函数,用于访问 T 数据
    {
        return &_inst;
    }

private:
    static T _inst;//静态数据成员。在该类范围中只能定义一个
    //规定 T 类对象只能通过 Signleton对象定义出来
    //这里采用静态成员意为 定义多个Signleton对象只能定义出一个T对象

};


int * p=Singleton_1<int> ::GetInstance();//这样就可以得到一个唯一的T类对象了


懒汉模式


template <class T>

class Singleton_2
{
public:
    static T * GetInstance()//第一次使用时 调用GetInstance()为T 类对象申请内存
    {
        if (_inst == NULL)
        {
            //LOCK  伪代码 加锁
            if (_inst == NULL)
            {
                _inst = new T();
            }
            //UNLOCK  伪代码  解锁
            return _inst;
        }
    }

private:
    volatile static T * _inst;//只是一个指针,需要初始化为NULL
};

//其实也是一种延时加载


注意

  1. 这种单例模式并不是一个线程安全模式,因为在判断_inst是否为空和开辟空间并不是原子操作
  2. 这种单例模式并不是一个线程安全模式,因为在判断_inst是否为空和开辟空间并不是原子操作
  3. 若是两个线程都执行到判断这一步,就会创建两个T 类对象,就会出现逻辑错误
  4. 所以要在判断和创建对象时加上互斥锁
  5. 有为了效率问题,我们只需要在_inst为空的时候再进行加锁
  6. 又为了防止编译器过度优化,我们确保每次判断的时候值都是从内从中读取的,我们需要对私有成员加上 volatile关键字

猜你喜欢

转载自blog.csdn.net/misszhoudandan/article/details/80737685
今日推荐