前言
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。为什
么会产生设计模式这样的东西呢?就像人类历史发展会产生兵法。最开始部落之间打仗时都是人拼人的对
砍。后来春秋战国时期,七国之间经常打仗,就发现打仗也是有套路的,后来孙子就总结出了《孙子兵
法》。孙子兵法也是类似。
使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编
写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。
一、单例模式是什么?
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全
局访问点,该实例被所有程序模块共享。
class Singleton
{
public:
static Singleton* GetInstance()
{
if (_pinst == nullptr)
{
_pinst = new Singleton;
}
return _pinst;
}
Singleton(const Singleton& s) = delete;
private:
Singleton()
{}
static Singleton* _pinst;
};
Singleton* Singleton::_pinst = nullptr;
int main()
{
/*Singleton s1;
Singleton s2;*/
cout << Singleton::GetInstance() << endl;
cout << Singleton::GetInstance() << endl;
cout << Singleton::GetInstance() << endl;
cout << Singleton::GetInstance() << endl;
//Singleton s(*Singleton::GetInstance());
return 0;
}
二、饿汉模式
//饿汉模式 一开始(main函数之前)就创建对象
class Singleton
{
public:
static Singleton* GetInstance()
{
return &_inst;
}
Singleton(const Singleton&) = delete;
private:
Singleton()
{}
static Singleton _inst;
};
Singleton Singleton::_inst;
三、懒汉模式
class Singleton
{
public:
static Singleton* GetInstance()
{
//_mutx.lock();
if (_pinst==nullptr)
{
unique_lock<mutex> lock(_mtx);
if (_pinst == nullptr)
{
_pinst = new Singleton;
}
}
//_mutx.unlock();
return _pinst;
}
static void DelInstance()
{
unique_lock<mutex> lock(_mtx);
delete _pinst;
_pinst = nullptr;
}
Singleton(const Singleton& s) = delete;
private:
Singleton()
{}
static Singleton* _pinst;
static mutex _mtx;
};
class GC
{
public:
~GC()
{
Singleton::DelInstance();
}
};
static GC gc;
Singleton* Singleton::_pinst = nullptr;
mutex Singleton::_mtx;
//int main()
//{
// /*Singleton s1;
// Singleton s2;*/
// cout << Singleton::GetInstance() << endl;
// cout << Singleton::GetInstance() << endl;
// cout << Singleton::GetInstance() << endl;
// cout << Singleton::GetInstance() << endl;
// //Singleton s(*Singleton::GetInstance());
// return 0;
//}
int main()
{
vector<thread> vthreads;
int n = 16;
for (int i = 0; i < n; i++)
{
vthreads.push_back(thread([]()
{
cout << Singleton::GetInstance() << endl;
}));
}
for (auto& e : vthreads)
{
e.join();
}
return 0;
}
总结
1.懒汉模式需要考虑线程安全和释放问题,实现相对更复杂,饿汉模式不存在以上问题,实现简单
2.懒汉是一种懒加载模式需要时在初始化创建对象,不会影响程序的启动。饿汉模式则相反,程序启动阶段就创建初始化实例对象,会导致程序启动慢,影响体验。
3.如果有多个单例类,假设有依赖关系,要求A先启动,B再启动,就不能用饿汉,因为无法保证创建初始化顺序,这时用懒汉我们就可以手动控制。
总结:实际中懒汉模式更实用一些