单例模式:只提供一个类的实例,且具有全局变量的特点。
1.static属性,全局只能有唯一一个实例,将构造函数私有化(private)禁止用户声明和定义
2.线程安全,禁止多个线程同时构造实例
3.禁止赋值和拷贝
4.使用static类成员函数获取实例
一、有缺陷的单例模式(存在线程安全和内存释放问题)
#include <iostream>
class singleTon
{
private:
//构造函数私有化
singleTon()
{
std::cout << "constructor called" << std::endl;
}
//单例模式类指针,静态变量并且私有化
static singleTon* m_instance_ptr;
//禁止拷贝和赋值
singleTon(singleTon&) = delete;
singleTon& operator = (const singleTon&) = delete;
public:
~singleTon()
{
std::cout << "destructor called" << std::endl;
}
static singleTon* getInstance()
{
if (m_instance_ptr == nullptr)
{
m_instance_ptr = new singleTon;
}
return m_instance_ptr;
}
};
singleTon* singleTon::m_instance_ptr = nullptr;
int main()
{
singleTon* instance1 = singleTon::getInstance();
singleTon* instance2 = singleTon::getInstance();
std::cout << "Hello World!\n";
}
二、线程安全,内存安全的单例模式(智能指针,加锁)
#include <iostream>
#include <memory>
#include <mutex>
class singleTon
{
public:
typedef std::shared_ptr<singleTon>singleTonPtr;//智能指针
~singleTon()
{
std::cout << "改进版单例模式析构函数,destructor called" << std::endl;
}
//禁止赋值和拷贝
singleTon(singleTon&) = delete;
singleTon& operator=(const singleTon&) = delete;
static singleTonPtr getInstance()
{
if (m_ptr == nullptr)
{
std::lock_guard<std::mutex>lk(m_mutex);
if (m_ptr == nullptr)
{
m_ptr = std::shared_ptr<singleTon>(new singleTon);
}
}
return m_ptr;
}
private:
//构造函数私有化
singleTon()
{
std::cout << "改进版单例模式构造函数,constructor called" << std::endl;
}
//私有化指针和锁(static)
static singleTonPtr m_ptr;
static std::mutex m_mutex;
};
singleTon::singleTonPtr singleTon::m_ptr = nullptr;
std::mutex singleTon::m_mutex;
#include <iostream>
int main()
{
singleTon::singleTonPtr a1 = singleTon::getInstance();
singleTon::singleTonPtr a2 = singleTon::getInstance();
}