单例模式
定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例可以分为饿汉单例和懒汉单例
饿汉式:类定义的时候就去实例化
优点:以空间换时间,不用担心多线程同步的问题
缺点:如果没有被使用,会浪费内存空间
懒汉式: 直到第一次使用时才实例化对象
优点:以时间换空间
缺点:需要考虑多线程同步的问题
代码:
#include <iostream>
#include <mutex>
using namespace std;
/*
饿汉式单例
饿汉式:类定义的时候就去实例化
优点:以空间换时间,不用担心多线程同步的问题
缺点:如果没有被使用,会浪费内存空间
问题:析构函数没有被调用
*/
class GloablLogHungry{
public:
GloablLogHungry(){
cout << "GloablLogHungry构造" << endl;
}
~GloablLogHungry(){
cout << "GloablLogHungry析构" << endl;
}
static GloablLogHungry* Instance(){
return m_instance;
}
void LogNorInfo()
{
cout << "饿汉单例记录正常日志" << endl;
}
void LogErrorInfo()
{
cout << "饿汉单例记录错误日志" << endl;
}
private:
static GloablLogHungry* m_instance;
};
GloablLogHungry* GloablLogHungry::m_instance = new GloablLogHungry();
/*
懒汉式:直到使用时才实例化对象
优点:以时间换空间
缺点:需要考虑多线程同步的问题
*/
/*
懒汉式单例 new
存在问题:析构函数没有执行 因为使用了new,如果没有显式的delete,会造成内存泄漏,
可以采用智能指针解决这个问题
*/
class GloablLogLazy{
public:
~GloablLogLazy(){
cout << "GloablLogLazy析构" << endl;
}
static GloablLogLazy* Instance(){
//局部静态对象
if (m_instance == nullptr)
{
std::lock_guard<std::mutex> lock(mutex); //上锁 自动释放
if (m_instance == nullptr) //防止其余线程继续创造实例
{
m_instance = new GloablLogLazy;
}
}
return m_instance;
}
void LogNorInfo()
{
cout << "懒汉单例1记录正常日志" << endl;
}
void LogErrorInfo()
{
cout << "懒汉单例1记录错误日志" << endl;
}
private:
static std::mutex m_mutex;
static GloablLogLazy *m_instance;
GloablLogLazy(){
cout << "GloablLogLazy构造" << endl;
} //防止对象被实例化
};
/*
懒汉式单例2 使用局部静态对象
优点:具有线程安全性,不需要释放堆内存
*/
class GloablLogLazylocal{
public:
~GloablLogLazylocal(){
cout << "GloablLogLazylocal析构" << endl;
}
//方式1
static GloablLogLazylocal* Instance(){
static GloablLogLazylocal instance;
return &instance;
}
void LogNorInfo()
{
cout << "懒汉单例2记录正常日志" << endl;
}
void LogErrorInfo()
{
cout << "懒汉单例2记录错误日志" << endl;
}
private:
GloablLogLazylocal(){
cout << "GloablLogLazylocal构造" << endl;
} //防止对象被实例化
};
int main()
{
//GloablLogLazy::Instance()->LogNorInfo();
//GloablLogLazy::Instance()->LogErrorInfo();
//推荐使用
GloablLogLazylocal::Instance()->LogNorInfo();
GloablLogLazylocal::Instance()->LogErrorInfo();
//GloablLogHungry::Instance()->LogNorInfo();
//GloablLogHungry::Instance()->LogErrorInfo();
return 0;
}