1、单例模式
单例模式:保证一个类只有一个对象实例,并提供一个访问该对象实例的全局访问点。
单例模式有两种实现方法:懒汉模式和饿汉模式。
2、饿汉模式
就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象。
优点:简单。
缺点:可能会导致进程启动慢,且如果有多个单例类对象实例启动顺序不确定。
在访问的线程比较多时,采用饿汉模式,可以实现更好的性能,这里是以空间换时间。饿汉模式线程是安全的,因为一开始已经对单例类进行的实例化。
#include <iostream>
class Singleton{
public:
static Singleton* getInstance()
{
return &_sin;
}
private:
//构造函数私有
Singleton(){}
//防拷贝
/*Singleton(const Singleton& s);*/
/*Singleton(const Singleton& s) = delete;*/
//禁止赋值
Singleton& operator=(const Singleton& s);
static Singleton _sin;
};
Singleton Singleton::_sin;
int main(){
Singleton* ps = Singleton::getInstance();
/*Singleton s(*ps);*/
Singleton* ps2 = Singleton::getInstance();
return 0;
}
3、懒汉模式
如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取文件啊等 等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,就会导致程序启动时 非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好。
优点:第一次使用实例对象时,创建对象。进程启动无负载。多个单例实例启动顺序自由控制。
缺点:复杂。
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
class Singleton{
public:
static Singleton* getIntance(){
if (_ps == nullptr){
_mtx.lock();
if (_ps == nullptr){
_ps = new Singleton;
}
_mtx.unlock();
}
return _ps;
}
//~Singleton(){
// if (_ps){
// //无线递归,导致栈溢出
// delete _ps;
// _ps = nullptr;
// }
//}
~Singleton(){
cout << "~Singleton()" << endl;
}
class GC{
public:
~GC(){
if (_ps){
delete _ps;
_ps = nullptr;
}
}
};
protected:
Singleton(){
for (int i = 0; i < 10000000; i++){
int b = i;
}
}
private:
Singleton(const Singleton& s);
static Singleton* _ps;
static mutex _mtx;
static GC _gc;
};
Singleton* Singleton::_ps = nullptr;
mutex Singleton::_mtx;
Singleton::GC Singleton::_gc;
void fun(){
for (int i = 0; i < 10; i++){
cout << i << endl;
}
}
void testSing(){
cout << Singleton::getIntance() << endl;
}
int main(){
Singleton* ps = Singleton::getIntance();
Singleton* ps2 = Singleton::getIntance();
int i = 0;
i++;
fun();
fun();
thread t1(fun);
thread t2(fun);
testSing();
testSing();
/*thread t1(testSing);
thread t2(testSing);*/
t1.join();
t2.join();
system("pause");
return 0;
}