单例(Singleton)模式
单例模式
单例模式旨在同一程序中,某个类只存在一个实例。解决此类问题的主要思想在于生成全局对象,本质是通过其在内存中位置不同,完成生存周期,及可见域的限制。使其存在与全局作用域,通过编译器来防止多个对象产生。
在面向对象中,我们通过singleton来完成对某的对向的单例化。
实现原则:
1. 私有构造函数,与拷贝构造
2. 静态实例引用(静态变量或静态指针)
3. Instance()接口
4. 通过类型的全局能力来在用编译器限制第二个singleton的产生。
分为懒汉模式和饿汉模式
懒汉式
实例通过类静态成员直接在类外初始化。从程序启动到程序终止一直存在。程序简单, 不好处在于,生存周期长,不可动态创建和销毁。
注意: 单例模式的重点在于内存中只有一个实例,我们并不关注程序中有多少个变量。因此, 我们不对拷贝构造进行私有化控制。
饿汉式
主要应用在实例的生存周期补丁,需要动态创建,动态销毁的状态。两次判断原因: 第一次判断为第一次创建与以后的创建做区别,减少了加锁的次数。
第二次判断为加锁后,防止多次new对象实例,做到了可重入。
#include <mutex>
#include <string>
#include <iostream>
#ifndef _DESIGN_PATTERN_SINGLETON_PATTERN_SINGLETON_
#define _DESIGN_PATTERN_SINGLETON_PATTERN_SINGLETON_
namespace design_pattern
{
/**
* lazy mode
*/
template <typename Ty>
class SingletonLazy
{
private:
SingletonLazy() {}
static Ty instance_;
public:
static Ty * Instance()
{
return &instance_;
}
};
template <typename Ty>
Ty SingletonLazy<Ty>::instance_;
/**
* hungry mode
*/
template <typename Ty>
class SingletonHungry
{
private:
SingletonHungry() {}
static Ty *pinstance_;
public:
static Ty *Instance()
{
if (nullptr == pinstance_)
{
std::mutex mtx;
mtx.lock();
if (nullptr == pinstance_)
pinstance_ = new Ty;
mtx.unlock();
}
return pinstance_;
}
};
template <typename Ty>
Ty * SingletonHungry<Ty>::pinstance_ = nullptr;
}
#endif //!_DESIGN_PATTERN_SINGLETON_PATTERN_SINGLETON_
//singleton_main.cpp
#include <iostream>
#include <string>
#include <thread>
#include "sigleton.hpp"
using namespace design_pattern;
using std::thread;
using std::string;
using std::cout;
using std::endl;
void GetInstance()
{
cout << "Lazy mode<string>:" << SingletonHungry<string>::Instance() << endl;
cout << "Hungry mode<int>:" << SingletonLazy<int>::Instance() << endl;
}
int main()
{
thread thd1(GetInstance);
thread thd2(GetInstance);
thd1.join();
thd2.join();
return 0;
}
懒汉式的推广
由懒汉式我们容易想到,只要内存区域具有全局性,获得实例的路径唯一,就可完成简单的对象单例化。
在linux的errno中,全局变量errno, oom机制中的oom_handle,使用静态局部变量,使用函数作为获得实例的路径。具有一定的封装性。缺少OO特性。
template <typename Ty>
Ty *InstanceHandle()
{
static Ty instance;
return &instance;
}
语法tips
- c++ 11 thread
- 构造
- join
- detach
- get_id
- joinable
- tative_handle
- operator=
- swap
- 函数内可以临时定义类型