单例设计模式

单例模式

定义

单例模式是指在整个系统生命周期内,保证一个类只能产生一个实例,确保该类的唯一性。

目的

单例模式是为了保证程序的线程安全。

1、有频繁实例化然后销毁的情况,也就是频繁的 new 对象,可以考虑单例模式;

2、创建对象时耗时过多或者耗资源过多,但又经常用到的对象;

3、频繁访问 IO 资源的对象,例如数据库连接池或访问本地文件;

4、Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。

单例类的特点

  • 构造函数和析构函数为私有类型,目的是禁止外部构造和析构。
  • 拷贝构造函数和赋值构造函数是私有类型,目的是禁止外部拷贝和赋值,确保实例的唯一性。
  • 类中有一个获取实例的静态方法,可以全局访问。

单例类

分类

单例模式可以分为 懒汉式 和 饿汉式 ,两者之间的区别在于创建实例的时间不同。

懒汉式:系统运行中,实例并不存在,只有当需要使用该实例时,才会去创建并使用实例。这种方式要考虑线程安全。(不写,不安全)

饿汉式:系统一运行,就初始化创建实例,当需要时,直接调用即可。这种方式本身就线程安全,没有多线程的线程安全问题。

代码实现

.h

// 饿汉实现 /

class Singleton
{
public:
    // 获取单实例
    static Singleton* GetInstance();
    // 释放单实例,进程退出时调用
    static void deleteInstance();    
    // 打印实例地址
    void Print();
private:
    // 将其构造和析构成为私有的, 禁止外部构造和析构
    Singleton();
    ~Singleton();
    // 将其拷贝构造和赋值构造成为私有函数, 禁止外部拷贝和赋值
    Singleton(const Singleton &signal);
    const Singleton &operator=(const Singleton &signal);
private:
    // 唯一单实例对象指针
    static Singleton *g_pSingleton;
};

.cpp

// 代码一运行就初始化创建实例 ,本身就线程安全
Singleton* Singleton::g_pSingleton = new (std::nothrow) Singleton();
Singleton* Singleton::GetInstance()
{
    return g_pSingleton;//只要有,一定不会被删除,就算将指针传递出去了,也不能调用析构函数,因为析构函数是私有的。
}
void Singleton::deleteInstance()
{
    if (g_pSingleton)
    {
        delete g_pSingleton;
        g_pSingleton = nullptr;
    }
}
void Singleton::Print()
{
    std::cout << "我的实例内存地址是:" << this << std::endl;
}
Singleton::Singleton()
{
    std::cout << "构造函数" << std::endl;
}
Singleton::~Singleton()
{
    std::cout << "析构函数" << std::endl;
}

static实现单例

借助static的全局变量的特性实现单例,特别适合用于map等数据结构的单例。
如下所示:

static CreateRegistry* kRegistry = new CreateRegistry();

或者使用static+callonce

static std::once_flag fg;
static std::map* ret = nullptr;
std::call_once(fg, [&] { ret = new std::map; });

你可能感兴趣的:(面试笔记,设计模式)