一、单例模式
1、饿汉式
1.1、基础版本
- 定义一个单例类
- 私有化构造函数,防止外界直接创建单例类的对象
- 禁用拷贝构造,移动赋值等函数,可以私有化,也可以直接使用=delete
- 使用一个公有的静态方法获取该实例
- 确保在第一次调用之前该实例被构造
#include <iostream>
#include <string>
using namespace std;
class Singleton {
protected:
Singleton() { std::cout << "Singleton: call Constructor\n"; };
static Singleton *m_pInst;
public:
Singleton(const Singleton &) = delete;
Singleton &operator=(const Singleton &) = delete;
virtual ~Singleton() { std::cout << "Singleton: call Destructor\n"; }
static Singleton* GetInstance() {
return m_pInst;
}
};
Singleton *Singleton::m_pInst = new Singleton;
int main()
{
Singleton *pInst1 = Singleton::GetInstance();
Singleton *pInst2 = Singleton::GetInstance();
cout << "pInst1 : " << pInst1 << endl;
cout << "pInst2 : " << pInst2 << endl;
return 0;
}
Singleton: call Constructor
pInst1 : 0xf71760
pInst2 : 0xf71760
Process returned 0 (0x0) execution time : 0.203 s
Press any key to continue.
1.2、基于资源管理的饿汉实现
1.2.1、智能指针解决方案
#include <iostream>
#include <string>
#include <mutex>
#include <memory>
#include <thread>
using namespace std;
class Singleton {
protected:
Singleton() { std::cout << "Singleton: call Constructor\n"; };
static shared_ptr<Singleton> instance;
private:
Singleton(const Singleton &) = delete;
Singleton &operator=(const Singleton &) = delete;
virtual ~Singleton() { std::cout << "Singleton: call Destructor\n"; }
public:
static void DestoryInstance(Singleton* x) {
delete x;
}
static shared_ptr<Singleton> GetInstance() {
return instance;
}
};
shared_ptr<Singleton> Singleton::instance(new Singleton(), DestoryInstance);
int main()
{
cout << "main开始" << endl;
thread t1([] {
shared_ptr<Singleton> s1 = Singleton::GetInstance();
});
thread t2([] {
shared_ptr<Singleton> s2 = Singleton::GetInstance();
});
t1.join();
t2.join();
cout << "main结束" << endl;
return 0;
}
Singleton: call Constructor
main开始
main结束
Singleton: call Destructor
Process returned 0 (0x0) execution time : 0.116 s
Press any key to continue.
1.2.2、静态嵌套类解决方案
#include <iostream>
#include <string>
#include <mutex>
#include <memory>
#include <thread>
using namespace std;
class Singleton {
class Deleter {
public:
Deleter() {};
~Deleter() {
if (m_pInst != nullptr) {
cout << "删除器启动" << endl;
delete m_pInst;
m_pInst = nullptr;
}
}
};
protected:
Singleton() { std::cout << "Singleton: call Constructor\n"; };
static Deleter m_deleter;
static Singleton* m_pInst;
private:
Singleton(const Singleton &) = delete;
Singleton &operator=(const Singleton &) = delete;
virtual ~Singleton() { std::cout << "Singleton: call Destructor\n"; }
public:
static Singleton* GetInstance() {
return m_pInst;
}
};
Singleton *Singleton::m_pInst = new Singleton;
Singleton::Deleter Singleton::m_deleter;
int main()
{
cout << "main开始" << endl;
thread t1([] {
Singleton *pInst1 = Singleton::GetInstance();
});
thread t2([] {
Singleton *pInst2 = Singleton::GetInstance();
});
t1.join();
t2.join();
cout << "main结束" << endl;
return 0;
}
Singleton: call Constructor
main开始
main结束
删除器启动
Singleton: call Destructor
Process returned 0 (0x0) execution time : 0.254 s
Press any key to continue.
2、懒汉式
2.1、基础版本
#include <iostream>
#include <string>
#include <mutex>
#include <memory>
#include <thread>
using namespace std;
class Singleton
{
public:
static Singleton* GetInstance() {
if (m_pInst == nullptr) {
m_pInst = new Singleton;
}
return m_pInst;
}
private:
Singleton() { cout << "构造函数启动。" << endl; };
~Singleton() { cout << "析构函数启动。" << endl; };
private:
static Singleton* m_pInst;
};
Singleton* Singleton::m_pInst = nullptr;
int main()
{
cout << "main开始" << endl;
thread t1([] {
Singleton *pInst1 = Singleton::GetInstance();
});
thread t2([] {
Singleton *pInst2 = Singleton::GetInstance();
});
t1.join();
t2.join();
cout << "main结束" << endl;
return 0;
}
2.2、双重检查
static Singleton* GetInstance() {
if (m_pInst == nullptr) {
lock_guard<mutex> l(m_mutex);
if (m_pInst == nullptr) {
m_pInst = new Singleton();
}
}
return m_pInst;
}
static Singleton* GetInstance() {
lock_guard<mutex> l(m_mutex);
if (m_pInst == nullptr) {
m_pInst = new Singleton();
}
return m_pInst;
}
2.3、基于静态局部对象的实现
#include <iostream>
#include <string>
#include <mutex>
#include <memory>
#include <thread>
using namespace std;
class Singleton
{
public:
static Singleton* GetInstance() {
static Singleton instance;
return &instance;
}
private:
Singleton() { cout << "构造函数启动。" << endl; };
~Singleton() { cout << "析构函数启动。" << endl; };
};
int main()
{
cout << "main开始" << endl;
thread t1([] {
Singleton *pInst1 = Singleton::GetInstance();
});
thread t2([] {
Singleton *pInst2 = Singleton::GetInstance();
});
t1.join();
t2.join();
cout << "main结束" << endl;
return 0;
}