您的位置:首页 > 其它

设计模式-------单例模式

2018-03-16 20:51 148 查看
简介

单例模式是最常用的设计模式之一,它属于创建型模式,它提供一种创建对象的最佳方式。保证一个类仅有一个
实例,并提供一个访问它的全局访问点。

单例模式不同的实现方式

1.饿汉模式:class Singleton
{
public:
static Singleton* GetInstance()
{
return instance;
}
private:
Singleton()
{
cout<<"Singleton()"<<endl;
}
static Singleton* instance ;
};
Singleton* Singleton::instance= new Singleton();//静态数据成员必须初始化

int main()
{
cout << "main run..." << endl; //验证静态对象的创建在main之前
Singleton* _s1 = Singleton::GetInstance();
Singleton* _s2 = Singleton::GetInstance();
cout << _s1 << endl;
cout << _s2 << endl;
//返回的是同一个对象
system("pause");
return 0;
}运行结果:



结论:饿汉模式顾名思义就是用空间换时间,并且是线程安全的。
2.懒汉模式class Singleton
{
public:
static Singleton* GetInstance()
{
if (instance == NULL) {
instance = new Singleton();
cout << "Obj success for" << endl;
}
else
cout << "Create failure" << endl;
return instance;
}
private:
Singleton()
{
cout << "Singleton()" << endl;
}
static Singleton* instance;
};
Singleton* Singleton::instance =NULL;//静态数据成员必须初始化
int main()
{
cout << "main run..." << endl; //验证静态对象的创建在main之前
Singleton* _s1 = Singleton::GetInstance();
Singleton* _s2 = Singleton::GetInstance();
cout << _s1 << endl;
cout << _s2 << endl;
//返回的是同一个对象
system("pause");
return 0;
}
运行结果:



结论:懒汉模式用饿汉模式相反,它是用时间换取空间,但线程不安全。
3.带双重检查的懒汉模式class Singleton
{
public:
volatile static Singleton* GetInstance()
{
//第一次检查实例是否存在
if (instance == NULL)
{
lock_guard<mutex> lock(_mtx);//调用即加锁,离开大括号作用域自动解锁
//第二次检查实例是否存在
if (instance == NULL)
{
instance = new Singleton();
cout << "Obj success for" << endl;

}
else
cout << "Create failure" << endl;

}

return instance;
}
private:
Singleton()
{
cout << "Singleton()" << endl;
}
volatile static Singleton* instance; //设置volatile关键字,防止被编译器优化
static mutex _mtx;
};
volatile Singleton* Singleton::instance = NULL;//静态数据成员必须初始化
mutex Singleton::_mtx;

int main()
{
cout << "main run..." << endl; //验证静态对象的创建在main之前
volatile Singleton* _s1 = Singleton::GetInstance();
volatile Singleton* _s2 = Singleton::GetInstance();
cout << _s1 << endl;
cout << _s2 << endl;
//返回的是同一个对象
system("pause");
return 0;
}
运行结果:



结论:先解释下为什么在同步块内还要再检验一次,因为可能会有多个线程一起进入同步块外的 if,如果在同步块内不进行二次检验的话就会生成多个实例了。这种实现版本,不仅安全且在多线程情况下能保持高性能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息