单例模式
单例模式,也叫单子模式,是一种常用的软件设计模式。 在应用这个模式时,单例对象的类必须保证只有一个实例存在。 许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。
懒汉式
不使用互斥(错误示范)
#include <iostream>
#include <thread>
using namespace std;
class Singelton
{
public:
static Singelton* GetInstance();
void FreeInstance();
private:
Singelton(); // 使构造函数私有
static Singelton* instance_;
};
Singelton* Singelton::instance_ = nullptr;
Singelton::Singelton()
{
cout << "构造函数:" << this << endl;
}
Singelton* Singelton::GetInstance()
{
// 没有锁,多线程下可能会多次实例化
if (instance_ == nullptr)
instance_ = new Singelton;
return instance_;
}
void Singelton::FreeInstance()
{
delete instance_;
instance_ = nullptr;
}
#pragma region 测试单例类
void thread_func(int id)
{
Singelton* instance = Singelton::GetInstance();
cout << "线程" << id << "获得实例:" << instance << endl;
}
int main()
{
thread t1(thread_func, 1);
thread t2(thread_func, 2);
t1.join();
t2.join();
cout << "运行结束" << endl;
}
#pragma endregion
Output |
---|
构造函数:01325468 线程1获得实例:01325468 构造函数:013316F0 线程2获得实例:013316F0 运行结束 |
使用互斥
#include <iostream>
#include <mutex>
using namespace std;
mutex singelton_mutex;
class Singelton
{
public:
static Singelton* GetInstance();
void FreeInstance();
private:
Singelton(); // 使构造函数私有
static Singelton* instance_;
};
Singelton* Singelton::instance_ = nullptr;
Singelton::Singelton()
{
cout << "构造函数:" << this << endl;
}
Singelton* Singelton::GetInstance()
{
if (instance_ == nullptr) // 双重锁定
{
lock_guard<mutex> lock(singelton_mutex);
if (instance_ == nullptr)
instance_ = new Singelton;
}
return instance_;
}
void Singelton::FreeInstance()
{
delete instance_;
instance_ = nullptr;
}
#pragma region 测试单例类
void thread_func(int id)
{
Singelton* instance = Singelton::GetInstance();
cout << "线程" << id << "获得实例:" << instance << endl;
}
int main()
{
thread t1(thread_func, 1);
thread t2(thread_func, 2);
t1.join();
t2.join();
cout << "运行结束" << endl;
}
#pragma endregion
Output |
---|
构造函数:00CA53D0 线程1获得实例:00CA53D0 线程2获得实例:00CA53D0 运行结束 |
饿汉式
#include <iostream>
#include <thread>
using namespace std;
class Singelton
{
public:
static Singelton* GetInstance();
private:
Singelton(); // 使构造函数私有
static Singelton* instance_;
};
Singelton* Singelton::instance_ = new Singelton;
Singelton::Singelton()
{
cout << "构造函数:" << this << endl;
}
Singelton* Singelton::GetInstance()
{
return instance_;
}
#pragma region 测试单例类
void thread_func(int id)
{
Singelton* instance = Singelton::GetInstance();
cout << "线程" << id << "获得实例:" << instance << endl;
}
int main()
{
thread t1(thread_func, 1);
thread t2(thread_func, 2);
t1.join();
t2.join();
cout << "运行结束" << endl;
}
#pragma endregion
Output |
---|
构造函数:0134A090 线程1 获得实例:0134A090 线程2 获得实例:0134A090 运行结束 |
call_once 实现单例类
#include <iostream>
#include <mutex>
using namespace std;
std::once_flag singelton_once_flag;
class Singelton
{
public:
static Singelton* GetInstance();
private:
Singelton(); // 使构造函数私有
static void CreateInstance();
static Singelton* instance_;
};
Singelton* Singelton::instance_ = nullptr;
Singelton::Singelton()
{
cout << "构造函数:" << this << endl;
}
void Singelton::CreateInstance()
{
instance_ = new Singelton;
cout << "创建实例:" << instance_ << endl;
}
Singelton* Singelton::GetInstance()
{
// CreateInstance 只会执行一次
std::call_once(singelton_once_flag, Singelton::CreateInstance);
return instance_;
}
#pragma region 测试单例类
void thread_func(int id)
{
Singelton* instance = Singelton::GetInstance();
cout << "线程" << id << "获得实例:" << instance << endl;
}
int main()
{
thread t1(thread_func, 1);
thread t2(thread_func, 2);
t1.join();
t2.join();
cout << "运行结束" << endl;
}
#pragma endregion
Output |
---|
构造函数:007D5468 创建实例:007D5468 线程2获得实例:007D5468 线程1获得实例:007D5468 运行结束 |