[设计模式] -- 单例模式

来源:互联网 发布:淘宝商品拍摄技巧 编辑:程序博客网 时间:2024/06/03 14:13

Emai : hahayacoder@gmail.com

 

背景

最近在公司的项目中,经常会用到单例模式,由于之前没有想过怎么正确使用单例模式,导致写成的程序中有BUG。在学习Cocos2d-x时,导演类CCDirector等都是单例类。所以从头开始学习单例模式。

 

介绍

单例模式也称为单件模式,单子模式.使用单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有模块共享.有很多地方需要这样的功能模块,如系统的日志输出、人物管理器等。单例模式一般实现方式为:将类的构造函数定义成私有,定义一个私有的静态变量指针指向类得唯一实例,并提供一个公有静态方法获取该实例

 

简单实现

//Singleton.h#ifndef SINGLETON_H#define SINGLETON_Hclass Singleton{public:    static Singleton* getInstance();    private:    Singleton();    static Singleton* m_singleton;};#endif // SINGLETON_H//Singleton.cpp#include "singleton.h"#include <iostream>using namespace std;//static变量的定义Singleton* Singleton::m_singleton = NULL;Singleton* Singleton::getInstance(){    if(NULL == m_singleton)    {        m_singleton = new Singleton();        cout << "Singleton Create..." << endl;    }    return m_singleton;}Singleton::Singleton(){}//main.cpp#include "singleton.h"#include <QtCore/QCoreApplication>int main(int argc, char *argv[]){QCoreApplication a(argc, argv);    Singleton *A = Singleton::getInstance();    Singleton *B = Singleton::getInstance();        return a.exec();}

运行结果:

从运行结果可以知道Singleton对象只创建了一次,即创建两个Singleton对象发现只打印出一次Create...即只调用了一次构造函数只生成了一个实例

 

深入思考

当在多线程中使用单例模式时(假设有AB两个线程),同时调用getInstance函数,初始时m_singletonNULL,当A线程调用getInstance时,执行到if(NULL==m_singleton)时,由于此时m_singletonNULL,默认情况下是要执行if里面的语句,但是由于CPU时间片到了等原因,先要去执行B线程,B线程执行到if(NULL==m_singleton)时,此时m_singleton同样为NULL。这种情况下就会出现问题,下面使用Qt中的互斥锁重写代码

//Singleton.h#ifndef SINGLETON_H#define SINGLETON_H#include <QMutex>#include <QMutexLocker>class Singleton{public:    static Singleton* getInstance();private:    Singleton();    //定义静态成员 静态成员不属于某个对象 是属于整个类    static Singleton* m_singleton;    static QMutex mutex;};#endif // SINGLETON_H//Singleton.cpp#include "singleton.h"#include <iostream>using namespace std;//static变量的定义QMutex Singleton::mutex;Singleton* Singleton::m_singleton = NULL;Singleton* Singleton::getInstance(){    //加锁    mutex.lock();    if(NULL == m_singleton)    {        m_singleton = new Singleton();        cout << "Singleton Create..." << endl;    }    //解锁    mutex.unlock();    return m_singleton;}Singleton::Singleton(){}


 

原创粉丝点击