C++ 单例模式

原创 2016年01月22日 17:12:52

单例模式Singleton(),应该是设计模式中最简单的一种模式,表明在整个程序执行周期内,类的实例对象只能存在一个。虽然很简单,但是应用场景却是很多,比如windows的任务管理器;windows的回收站,在整个系统运行中,回收站一直维护着一个实例;应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。

UML_Singleton

class CSingleton
{
public:
    static CSingleton* getInstance()
    {
        if (m_pInstance == NULL)
        {
            m_pInstance = new CSingleton;
        }

        return m_pInstance;
    }

protected:
    CSingleton() {}
    virtual ~CSingleton() {}

private:
    static CSingleton* m_pInstance;
};

CSingleton* CSingleton::m_pInstance = NULL;

上面的代码是最简单的一种单例模式实现,主要有几个地方需要注意。首先是单例模式只能通过getIntance() 实现,而不能通过构造函数的方式实现,所以必须设置构造函数是私有的或者保护的。其次,既然只能在整个程序运行周期存在一个对象,那么私有的成员变量应该设置为静态变量,同理,那么函数的修改也应该是静态。静态成员变量只能在类外显示声明,因为它不属于某一个对象,而属于这个类共享。


程序代码最终是希望有良好的扩展性和稳定性,如果上面的代码在多线程环境中,肯定不能保证实例对象只存在一个,所以需要修改在多线程中是满足单例模式的定义。其次,单例模式希望实例的是某种类型或者性质的对象,那么需要修改为模板类的定义,这样在以后的需求改动中,就避免了不避免的麻烦。

template <typename T>
class CSingleton
{
public:
    static T* getInstance()
    {
        if (NULL == m_pInstance)
        {
            boost::unique_lock<boost::mutex> Lock(m_Mutex);
            if (NULL == m_pInstance)
            {
                //std::cout << "Thread id" << boost::this_thread::get_id() << std::endl;
                m_pInstance = new T;
            }
        }

        return m_pInstance;
    }

protected:
    CSingleton(void) {}
    virtual ~CSingleton(void) {}

private:
    static T* m_pInstance;
    static boost::mutex m_Mutex;
};

template<typename T>
T* CSingleton<T>::m_pInstance = NULL;

template<typename T>
boost::mutex CSingleton<T>::m_Mutex;

首先是模板形式,这个比较简单,读者能一眼看出其修改方式。其他改动的地方首先是if (NULL == m_pInstance) 判断为空条件写了两个,第一个是为了避免加锁解锁的耗时操作,多线程中互斥量的加锁解锁比较耗时的,所以在以后不为空的情况,都没必要进行加锁解锁,只有在第一次为空的情况,才到内部就行加锁操作。


程序代码健壮了,但是类的析构函数也是私有的,那说明如果有程序员想显示delete是不可能,那么只能增加相应的函数去删除对象。

template <typename T>
class CSingleton
{
public:
    static T* getInstance()
    {
        if (NULL == m_pInstance)
        {
            boost::unique_lock<boost::mutex> Lock(m_Mutex);
            if (NULL == m_pInstance)
            {
                //std::cout << "Thread id" << boost::this_thread::get_id() << std::endl;
                m_pInstance = new T;
                atexit(destroy);
            }
        }

        return m_pInstance;
    }

    static void destroy()
    {
        if (m_pInstance)
        {
            delete m_pInstance;
            m_pInstance = NULL;
        }
    }

protected:
    CSingleton(void) {}
    virtual ~CSingleton(void) {}

private:
    static T* volatile m_pInstance;
    static boost::mutex m_Mutex;
};

template<typename T>
T* volatile CSingleton<T>::m_pInstance = NULL;

template<typename T>
boost::mutex CSingleton<T>::m_Mutex;

上面的代码多了destroy函数来delete对象,和int atexit (void (*function) (void)); 来调用它,atexit()用来设置一个程序正常结束前调用的函数. 当程序通过调用exit()或从main 中返回时, 参数function 所指定的函数会先被调用, 然后才真正由exit()结束程序。
而C++关键volatile关键字,多线程的volatile,当两个线程都要用到某一个变量且该变量的值会被改变时,应该用 volatile 声明,该关键字的作用是防止优化编译器把变量从内存装入 CPU 寄存器中。如果变量被装入寄存器,那么两个线程有可能一个使用内存中的变量,一个使用寄存器中的变量,这会造成程序的错误执行。volatile 的意思是让编译器每次操作该变量时一定要从内存中真正取出,而不是使用已经存在寄存器中的值。详细参考C/C++ volatile让你看的更明白

参考资料:
【1】http://blog.csdn.net/likika2012/article/details/11483167
【2】http://www.jellythink.com/archives/82
【3】https://gist.github.com/daniebker/2299755
【4】http://blog.csdn.net/wwang196988/article/details/6623387

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

c++ 单例模式源码

  • 2011-08-17 09:20
  • 571B
  • 下载

c++线程安全单例模式

单例模式及C++实现代码

单例模式 单例模式,可以说设计模式中最常应用的一种模式了,据说也是面试官最喜欢的题目。但是如果没有学过设计模式的人,可能不会想到要去应用单例模式,面对单例模式适用的情况,可能会优先考虑使用全局或者静...

C++单例模式

C++中的单例模式

  • 2012-12-29 11:48
  • 51KB
  • 下载

(C++)用模板或宏实现单例模式

(C++)用模板或宏实现单例模式 http://blog.csdn.net/nono_o/article/details/43909757?ref=myread 最近在coco...

C++单例模式示例代码

C++中的单例模式(★好文章firecat推荐,多关注原作者的博客★)

文章来源:http://blog.csdn.net/hackbuteer1/article/details/7460019 单例模式也称为单件模式、单子模式,可能是使用最广泛的设计模式。其意图是保证...

C++ 单例模式

内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)