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

Emai : hahayacoder@gmail.com

 

背景

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

 

介绍

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

 

简单实现

//Singleton.h
#ifndef SINGLETON_H
#define SINGLETON_H
class 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()
{

}


 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值