单例模式简介
1.单例类只有一个实例存在
2.必须有这个类本身自行创建实例
3.面向整个系统提供这个实例
任务管理器使用单例模式
单例模式分为饿汉式和懒汉式两种
创建步骤:
1.构造函数私有化
如果构造函数是公共的,那么就可以在类外无限的创建实例。当构造函数是私有的,那么就不能在类外创建实例
2.定义一个静态指针指向实例
在系统的静态区创建一个实例,利用一个静态指针指向这块区域
3.提供一个全局的静态方法来获取这个类的实例
在类的公共区域提供一个静态接口函数,返回静态指针
饿汉式
#include<iostream>
using namespace std;
class signleton
{
public:
static signleton *getinstance()
{
return instance;
}
private:
signleton()
{
}
static signleton *instance;
};
signleton *signleton::instance = new signleton;//编译器就创建了类的实例
int main()
{
signleton *s1 = signleton::getinstance();
signleton *s2 = signleton::getinstance();
if(s1==s2)
cout<<"s1==s2"<<endl;
else
cout<<"s1!=s2"<<endl;
system("pause");
return 0;
}
懒汉式是在编译器就创建了类的唯一实例,不管这个类是否被调用,这样做会占用一部分内存
懒汉式
#include<iostream>
using namespace std;
class signleton
{
public:
static signleton *getinstance()
{
if(instance==NULL)
instance = new signleton;
return instance;
}
private:
signleton()
{
}
static signleton *instance;
};
int main()
{
signleton *s1 = signleton::getinstance();
signleton *s2 = signleton::getinstance();
if(s1==s2)
cout<<"s1==s2"<<endl;
else
cout<<"s1!=s2"<<endl;
system("pause");
return 0;
}
懒汉式是当类被调用时,才创建这个类的唯一实例
当懒汉式遇到多线程
当存在多个线程同时调用单例类的时候,会竞争静态接口函数的资源
1.当thread1调用get函数,此时instance为空,则会new一个实例。
2.在thread1刚new了一个实例之后,并没有为instance赋值,所以此时instance仍然为空,所以thread2也new了一个实例
3.上述过程共new了两次,不符合单例模式基本思想
改进
将给函数加上锁
#include<iostream>
using namespace std;
#include<mutex>
//懒汉式
mutex mu;
class signleton
{
public:
static signleton *getinstance()
{
mu.lock();
if(instance==NULL)
instance = new signleton;
return instance;
mu.unlock();
}
private:
signleton()
{
}
static signleton *instance;
};