单例模式的学习笔记
单例模式是为了:在整个系统生命周期内,保证一个类只能产生一个实例,确保该类的唯一性
cpp
#include <iostream>
#include <mutex>
using namespace std;
/*懒汉模式:只有在用到了才实例化对象并返回(调用了对外的接口才会实例对象)*/
/*构造函数私有化,只对外提供一个接口*/
/*线程不安全*/
class singleClass {
public:
static singleClass* getInstance() // 对外接口,静态成员函数调用静态成员变量
{
if (m_instance == nullptr) // 在多线程的环境下,在判空的时候可能存在多个线程同时进入if中,此时可能会实例化多个对象
{
m_instance = new singleClass();
}
return m_instance;
}
private:
static singleClass* m_instance; // 静态成员变量,类内声明,类外初始化
singleClass() {} // 构造函数属性设置为私有
singleClass (const singleClass & sc) {} // 拷贝构造函数也设置为私有
};
singleClass* singleClass::m_instance = nullptr; // 初始化静态变量
/*线程安全*/
class threadSingleClass
{
public:
static threadSingleClass* getInstance()
{
if (m_instance == nullptr) // 先判断是否为空,为空就进入;不为空,说明已经存在实例,返回
{
//m_mutex.lock(); // 这里如果使用unique_lock就不需要在下面解锁
unique_lock<mutex> lock(m_mutex);
if (m_instance == nullptr) // 再次判断,确保不会因为加锁期间多个线程同时进入
{
m_instance = new threadSingleClass();
}
//m_mutex.unlock();
}
return m_instance;
}
private:
static threadSingleClass* m_instance;
static mutex m_mutex;
threadSingleClass() {};
threadSingleClass(const threadSingleClass& sc) {}
};
threadSingleClass* threadSingleClass::m_instance = nullptr;
mutex threadSingleClass::m_mutex;
/*饿汉模式:不管调不调用对外接口,都已经实例化对象了。本身就是线程安全的*/
/*类在加载的时候就实力化对象,所以要提前占用系统资源*/
class hungrySingleClass
{
public:
static hungrySingleClass* getInstance()
{
return m_instance;
}
private:
static hungrySingleClass* m_instance;
hungrySingleClass() {}
hungrySingleClass(const hungrySingleClass* sc) {} // 拷贝构造私有
};
hungrySingleClass* hungrySingleClass::m_instance = new hungrySingleClass();
// 类外定义,main开始执行前,该对象就存在了
int main()
{
singleClass* singlep1 = singleClass::getInstance();
singleClass* singlep2 = singleClass::getInstance();
cout << singlep1 << endl;
cout << singlep2 << endl;
threadSingleClass* thsinglep1 = threadSingleClass::getInstance();
threadSingleClass* thsinglep2 = threadSingleClass::getInstance();
cout << thsinglep1 << endl;
cout << thsinglep2 << endl;
hungrySingleClass* hgsinglep1 = hungrySingleClass::getInstance();
hungrySingleClass* hgsinglep2 = hungrySingleClass::getInstance();
cout << hgsinglep1 << endl;
cout << hgsinglep2 << endl;
system("pause");
return 0;
}