单例模式——C++实现

一、什么是单例模式模式?

单例模式是常用的基础设计模式,单例模式指在整个系统生命周期里,保证一个类只能产生一个实例,确保该类的唯一性。

单例模式分类

单例模式可以分为懒汉式和饿汉式,两者之间的区别在于创建实例的时间不同:
懒汉式:程序开始运行时单例并不存在,只有当需要使用该实例时,才会去创建并使用实例。(这种方式要考虑线程安全)
饿汉式:程序开始运行时就初始化创建实例,当需要时,直接调用即可。(本身就线程安全,没有多线程的问题)

单例类特点
  1. 构造函数和析构函数为private类型,目的禁止外部构造和析构
  2. 拷贝构造和赋值构造函数为private类型,目的是禁止外部拷贝和赋值,确保实例的唯一性
  3. 类里有个获取实例的静态函数,可以全局访问

二、懒汉模式(单线程,线程不安全)

简单的单例模式实现,可以在单线程下使用,多线程模式下会造成线程不安全。

#include 
using namespace std;

class Singleton
{
    public:
    //获取单例对象
    static Singleton * GetInstance();
    //释放单例对象
    static void DeleteInstance();

    private:
    //把构造函数、拷贝构造函数、赋值构造函数私有化,这样在类外就只能通过我们给出的接口函数获取实例了
    Singleton();
    ~Singleton();

    Singleton(const Singleton &);
    Singleton & operator=(const Singleton &);
    // 唯一单例对象指针
    static Singleton * p;
};
//类外初始化静态成员变量
Singleton * Singleton::p=nullptr;

Singleton::Singleton()
{

}
Singleton::~Singleton()
{

}

Singleton * Singleton::GetInstance()
{
    if(p==nullptr)
    {
        p=new Singleton();
    }
    return p;
}

void Singleton::DeleteInstance()
{
    if(p)
    {
        delete p;
        p=nullptr;
    }
}

三、懒汉模式(加锁,线程安全)

#include 
#include
using namespace std;


class Singleton
{
    public:
    //获取单例对象
    static Singleton * GetInstance();
    //释放单例对象
    static void DeleteInstance();

    private:
    //把构造函数、拷贝构造函数、赋值构造函数私有化,这样在类外就只能通过我们给出的接口函数获取实例了
    Singleton();
    ~Singleton();

    Singleton(const Singleton &);
    Singleton & operator=(const Singleton &);
    // 唯一单例对象指针
    static Singleton * p;
    static pthread_mutex_t lock;

};
//类外初始化静态成员变量
Singleton * Singleton::p=nullptr;
pthread_mutex_t Singleton::lock=PTHREAD_MUTEX_INITIALIZER;

Singleton::Singleton()
{

}
Singleton::~Singleton()
{

}


Singleton * Singleton::GetInstance()
{
    //最外层的if(p==nullptr),目的是为了尽量避免加锁,毕竟加锁的开销有点大
    if(p==nullptr)
    {
        pthread_mutex_lock(&lock);
        if(p==nullptr)
        {
            p=new Singleton();
        }
        pthread_mutex_unlock(&lock);
    }
    return p;
}
void Singleton::DeleteInstance()
{
     pthread_mutex_lock(&lock);
     if(p)
     {
        delete p;
        p=nullptr;
     }
     pthread_mutex_unlock(&lock);
}

四、懒汉模式(线程安全,静态局部变量特性)

c++11特性,static修饰局部变量时,局部变量将会在全局数据区分配内存,直到程序运行结束才会释放内存,并且可以通过引用或指针在函数外部使用该局部变量。静态局部变量只初始化一次(实测是在第一次调用时初始化),之后每次调用函数时不再重新赋值,具有线程安全特性。在定义静态局部变量时不赋值的话,会执行默认初始化。

#include
using namespace std;

class Singleton
{
    public:
    static Singleton & GetInstance();

    private:
    //把构造函数、拷贝构造函数、赋值构造函数私有化,这样在类外就只能通过我们给出的接口函数获取实例了
    Singleton();
    ~Singleton();

    Singleton(const Singleton &);
    Singleton & operator=(const Singleton &);

};


Singleton::Singleton()
{

}
Singleton::~Singleton()
{

}
Singleton & Singleton::GetInstance()
{
    // 局部静态特性的方式实现单实例
    static Singleton single;
    return single;
}

五、饿汉模式

#include 
using namespace std;

class Singleton
{
    public:
    //获取单例对象
    static Singleton * GetInstance();
    private:
    //把构造函数、拷贝构造函数、赋值构造函数私有化,这样在类外就只能通过我们给出的接口函数获取实例了
    Singleton();
    ~Singleton();

    Singleton(const Singleton &);
    Singleton & operator=(const Singleton &);
    // 唯一单例对象指针
    static Singleton * p;

};
//类外初始化静态成员变量
Singleton * Singleton::p=new Singleton();

Singleton::Singleton()
{

}
Singleton::~Singleton()
{

}

Singleton * Singleton::GetInstance()
{
    return p;
}

你可能感兴趣的:(单例模式,c++,设计模式)