(一)单例模式

在项目或面试中,最有可能遇到的就是单例模式,所以,能够手写一个单例模式是学习设计模式的基本功之一。

1. 单例模式

单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。

所有的单例模式都是使用静态方法进行创建的,所以单例对象在内存中静态共享区中存储。

应用场景(参考:《大话设计模式》):
1) 需求:在前端创建工具箱窗口,工具箱要么不出现,出现也只出现一个
遇到问题:每次点击菜单都会重复创建“工具箱”窗口。
解决方案一:使用if语句,在每次创建对象的时候首先进行判断是否为null,如果为null再创建对象。

2) 需求:如果在5个地方需要实例出工具箱窗体
遇到问题:这个小bug需要改动5个地方,并且代码重复,代码利用率低
解决方案二:利用单例模式,保证一个类只有一个实例,并提供一个访问它的全局访问点。

单例模式可以分为懒汉式和饿汉式:

  • 懒汉式:在类加载时不初始化。
  • 饿汉式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。

2. 示例:双重校验锁

#ifndef SINGLETON_PATTERN_H
#define SINGLETON_PATTERN_H

#include <iostream>
#include <mutex>

class CSingleton
{
public:
    /* 删除器类 */
    class DeleteInstance
    {
    public:
        ~DeleteInstance()
        {
            std::cout << "DeleteInstance's destructor called." << std::endl;
            if (CSingleton::m_pSingleton)
            {
                delete CSingleton::m_pSingleton;
            }
        }
    };

    static DeleteInstance deleteInstance;   ///< 删除器类实例

public:
    /* 获取实例的全局访问点 */
    static CSingleton* GetInstance()
    {
        /* 双检锁 */
        if (nullptr == m_pSingleton)
        {
            std::lock_guard<std::mutex> lgLock(m_mutex);
            if (nullptr == m_pSingleton)
            {
                m_pSingleton = new CSingleton();
            }
        }
        return m_pSingleton;
    }

    ///* destructor */
    //~CSingleton()
    //{
    //    std::cout << "CSingleton's destructor called." << std::endl;
    //    delete m_pSingleton;
    //}

private:
    /* private constructor */
    CSingleton()
    {
        std::cout << "CSingleton's constructor called." << std::endl;
    }

    /* private copy constructor */
    CSingleton(const CSingleton&) = delete;

    /* private operator = */
    CSingleton& operator=(const CSingleton&) = delete;

private:
    static CSingleton   *m_pSingleton;   ///< 静态实例
    static std::mutex    m_mutex;        ///< 多线程时的单例, 保证线程安全
};

/* static 成员的初始化, 这些东西最好放在CPP文件中, 以免会产生重复定义问题 */
CSingleton*                CSingleton::m_pSingleton = nullptr;    ///< 懒汉式, 在第一次被引用时,才会实例化.
std::mutex                  CSingleton::m_mutex;                         ///< static mutex 初始化
CSingleton::DeleteInstance CSingleton::deleteInstance;      ///< 删除器, 在程序结束时调用析构函数, 删除 m_pSingleton.

#endif // SINGLETON_PATTERN_H

3. 参考

posted @ 2018-08-20 15:28  yvhqbat  阅读(175)  评论(0编辑  收藏  举报