【C++】实现Singleton模式

单例模式,就是设计一个类,我们只能生成该类的一个实例。
而单例模式的实现方式有两种:懒汉模式和饿汉模式

懒汉模式

懒汉式是典型的时间换空间,也就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,那就不会创建实例,则节约内存空间。

实现1、教科书

构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实例的动作由一个public的类方法代劳,该方法也返回单例类唯一的实例。

class Singleton
{
private:
    Singleton() //私有构造函数
    {}
    static Singleton* _instance;
public:
    static Singleton* getInstace();//静态成员方法获取实例
};

Singleton* Singleton::_instance = NULL;
Singleton* Singleton::getInstace()
{
    if (_instance == NULL)
        _instance = new Singleton();
    return _instance;
}

这是一个很棒的实现,简单易懂。但这是一个完美的实现吗?不!该方法是线程不安全的,考虑两个线程同时首次调用instance方法且同时检测到p是NULL值,则两个线程会同时构造一个实例给p,这是严重的错误!同时,这也不是单例的唯一实现!

线程安全的懒汉模式

(1)加锁的经典懒汉实现

class Singleton1
{
protected:
    Singleton1()
    {
        pthread_mutex_init(&mutex);
    }
private:
    static Singleton1* p;
public:
    static pthread_mutex_t mutex;
    static Singleton1* initance();
};

pthread_mutex_t Singleton1::mutex;
Singleton1* Singleton1::p = NULL;
Singleton1* Singleton1::initance()
{
    if (p == NULL)
    {
        pthread_mutex_lock(&mutex);
        if (p == NULL)
            p = new Singleton1();
        pthread_mutex_unlock(&mutex);
    }
    return p;
}

(2)内部静态变量的懒汉实现

class Singleton3
{
protected:
    Singleton3()
    {
        pthread_mutex_init(&mutex);
    }
public:
    static pthread_mutex_t mutex;
    static Singleton3* initance();
};

pthread_mutex_t Singleton3::mutex;
Singleton3* Singleton3::initance()
{
    pthread_mutex_lock(&mutex);
    static Singleton3 obj;
    pthread_mutex_unlock(&mutex);
    return &obj;
}
饿汉模式

饿汉式是典型的空间换时间,当类装载的时候就会创建类实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要再判断了,节省了运行时间。

注:饿汉模式本身就是线程安全的。

class singleton
{
protected:
  singleton()
  {}
private:
  static singleton* p;
public:
  static singleton* initance();
};
singleton* singleton::p = new singleton;
singleton* singleton::initance()
{
  return p;
}
两种模式的区别

由于要进行线程同步,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现,可以实现更好的性能。这是以空间换时间。

在访问量较小时,采用懒汉实现。这是以时间换空间。

单利模式的释放

class CSingleton:
{
    // 其它成员  
public:  
    static CSingleton * GetInstance()  
private:  
    CSingleton(){};  
    static CSingleton * m_pInstance;  
    class CGarbo // 它的唯一工作就是在析构函数中删除CSingleton的实例  
    {
    public:
        ~CGarbo()
        {  
            if (CSingleton::m_pInstance)
                delete CSingleton::m_pInstance;
        }
    };
    static CGarbo Garbo; // 定义一个静态成员,在程序结束时,系统会调用它的析构函数
};

类CGarbo被定义为CSingleton的私有内嵌类,以防该类被在其它地方滥用。

在程序运行结束时,系统会调用CSingleton的静态成员Garbo的析构函数,该析构函数会删除单例的唯一实例。

使用这种方法释放C++单例模式对象有以下特征:

在单例类内部定义专有的嵌套类。

在单例类内定义私有的专门用于释放的静态成员。

利用程序在结束时析构全局变量的特性,选择最终的释放时机。

使用C++单例模式的代码不需要任何操作,不必关心对象的释放。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值