单例模式(Singleton):
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例模式分为懒汉模式和饿汉模式,以及在创建实例的时候要考虑多线程问题,也就是需要上锁,上锁可以采用一般的锁,也可以采用双重锁的方式减少上锁时内核态与用户态切换导致的资源浪费,同时因为饿汉模式的特性,饿汉模式不涉及到多线程上锁问题。
接下来实现一下懒汉模式和饿汉模式,先不考虑多线程问题,最后在单独说下多线程问题的处理代码。
单例模式(懒汉)
.h
#pragma once
#include <iostream>
using namespace std;
class CWork
{
private:
static CWork * m_cWork;
static int m_nMarkRunCount;
CWork(){} //By using the constructor as a private block to prevent users from using the class variable.
void DoWrite()
{
cout<<"WorkCount:"<<m_nMarkRunCount++<<endl;
}
public:
static void GetInstance()
{//Create a static function of the entity
if(m_cWork == NULL)
{
m_cWork = new CWork();
}
}
static void WriteLog()
{//work function
if(m_cWork == NULL)
{
cout<<"no instance"<<endl;
return ;
}
m_cWork->DoWrite();
}
};
.cpp
#include "stdafx.h"
#include "SingletonMode.h"
CWork * CWork::m_cWork = NULL;
int CWork::m_nMarkRunCount = 0;
客户端调用:
#include "stdafx.h"
#include "SingletonMode.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
CWork::WriteLog();
CWork::GetInstance();
CWork::WriteLog();
CWork::WriteLog();
return 0;
}
运行结果:单例模式(饿汉)
.h
#pragma once
#include <iostream>
using namespace std;
class CWork
{
private:
static CWork * m_cWork;
static int m_nMarkRunCount;
CWork(){} //By using the constructor as a private block to prevent users from using the class variable.
void DoWrite()
{
cout<<"WorkCount:"<<m_nMarkRunCount++<<endl;
}
public:
static CWork* GetInstance()
{//Create a static function of the entity
if(m_cWork == NULL)
{
m_cWork = new CWork();
}
return m_cWork;
}
static void WriteLog()
{//work function
if(m_cWork == NULL)
{
cout<<"no instance"<<endl;
return ;
}
m_cWork->DoWrite();
}
};
.cpp
#include "stdafx.h"
#include "SingletonMode.h"
CWork * CWork::m_cWork = CWork::GetInstance();
int CWork::m_nMarkRunCount = 0;
客户端调用:
#include "stdafx.h"
#include "SingletonMode.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
CWork::WriteLog();
CWork::WriteLog();
CWork::WriteLog();
return 0;
}
运行结果:
Static void GetInstance()
{
If(m_cWork == NULL)
{
Lock
{
If(m_cWork == NULL)
{
m_cWork = new CWork();
}
}
}
}//注意第二个if的作用。