(七)boost库之单例类
(七)boost库之单例类
一、boost.serialzation的单件实现
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
单例,通常在一个大型项目中单例是非常常见的,boost库没有提供专门的单例类,但可以在其它库中找到他的实现
#include <boost/serialization/singleton.hpp>
class ThreadPoll : public boost::serialization::singleton<ThreadPoll>
{
};
当然,你也可以不使用继承的方式,只需要typedef一下,就可以得到一个全局访问点,这种方式会更加的灵活。
class ThreadPoll
{
};
typedef boost::serialization::singleton<ThreadPoll> ThreadPollAgent;
但是,该单例是非线程安全的,单件类实现了一个全局访问点,如果在多个线程环境中访问,是需要自行加锁的,因此,如果需要一个线程安全的单件,需要自己实现。
二、自行实现线程安全单件
/******************************************************
* 支持线程安全的单例类
*******************************************************/
#ifndef __SINGLETON_H__
#define __SINGLETON_H__
#include <boost/noncopyable.hpp>
#include <boost/thread.hpp>
//哨兵类,负责多线程操作,自动加锁解锁
//哨兵类不允许拷贝,
template<typename T>
class SingletonGuard : boost::mutex::scoped_lock, public boost::noncopyable
{
public:
explicit SingletonGuard(T* inst, boost::mutex& mt):boost::mutex::scoped_lock(mt),m_guardPtr(inst)
{
}
T* operator->()
{
return m_guardPtr;
}
private:
T* m_guardPtr;
};
//监视类,用于监视单例的状态
template<typename T>
class Singleton_wrapper : public T
{
public:
static bool m_is_destroyed;
~Singleton_wrapper(){
m_is_destroyed = true;
}
};
template<typename T>
bool Singleton_wrapper< T >::m_is_destroyed = false;
//单例
template<typename T>
class Singleton : public boost::noncopyable
{
public:
static SingletonGuard<T> get_mutable_instance(){
return SingletonGuard<T>(&get_instance(), m_signalMutex);
}
static const T & get_const_instance(){
return get_instance();
}
private:
static T & instance;
static void use(T const &) {}
static T & get_instance() {
static Singleton_wrapper< T > t;
//编译期进行初始化实例
BOOST_ASSERT(! Singleton_wrapper< T >::m_is_destroyed);
use(instance);
return static_cast<T &>(t);
}
static boost::mutex m_signalMutex;
protected:
boost::mutex::scoped_lock ScopedLock()
{
return boost::mutex::scoped_lock(m_signalMutex);
}
};
template<typename T>
boost::mutex Singleton< T >::m_signalMutex;
template<typename T>
T & Singleton< T >::instance = Singleton< T >::get_instance();
#endif //__SINGLETON_H__
该类参考boost单件的实现,使用上相似,但get_mutable_instance返回的不是实例对象,而是保存该实例指针的一个临时变量,通过定义->符号访问实例的函数,离开该作用域时,临时变量析构,
自行解锁。通过该单例访问的所有函数都将已加锁的形式进行访问,如果想在不加锁的情况下访问,只能通过get_const_instance获取实例的方式访问。
你可以像下面这样使用:
class ThreadPoll
{
public:
void Update(){};
int Query()const{};
};
typedef Singleton<ThreadPoll> ThreadPollAgent;
ThreadPollAgent::get_mutable_instance()->Update();
ThreadPollAgent::get_const_instance().Query();
(七)boost库之单例类的更多相关文章
- muduo网络库源码学习————线程本地单例类封装
muduo库中线程本地单例类封装代码是ThreadLocalSingleton.h 如下所示: //线程本地单例类封装 // Use of this source code is governed b ...
- c++:自己动手实现线程安全的c++单例类
前段时间使用c++做项目开发,需要根据根据配置文件路径加载全局配置文件,并对外提供唯一访问点.面对这样一个需求,自然的就想到了使用单例模式来创建一个单例配置对象,供外部调用.一开始想使用boost中自 ...
- C++解析(27):数组、智能指针与单例类模板
0.目录 1.数组类模板 1.1 类模板高效率求和 1.2 数组类模板 1.3 堆数组类模板 2.智能指针类模板 2.1 使用智能指针 2.2 智能指针类模板 3.单例类模板 3.1 实现单例模式 3 ...
- 设计模式——懒汉式单例类PK饿汉式单例类
前言 我们都知道生活中好多小软件,有的支持多IP在线,有的仅仅局限于单个IP在线.为什么这样设计,在软件开发阶段就是,有需求就是发展.这就是软件开发的一个设计模式--懒汉式单例类和饿汉式单例类. 内容 ...
- java单例类/
java单例类 一个类只能创建一个实例,那么这个类就是一个单例类 可以重写toString方法 输出想要输出的内容 可以重写equcal来比较想要比较的内容是否相等 对于final修饰的成员变量 一 ...
- iOS中编写单例类的心得
单例 1.认识过的单例类有哪些: NSUserDefaults.NSNotificationCenter.NSFileManager.UIApplication 2.单例类 单例类某个类在代码编写时使 ...
- 如何防止JAVA反射对单例类的攻击?
在我的上篇随笔中,我们知道了创建单例类有以下几种方式: (1).饿汉式; (2).懒汉式(.加同步锁的懒汉式.加双重校验锁的懒汉式.防止指令重排优化的懒汉式); (3).登记式单例模式; (4).静态 ...
- 0013 Java学习笔记-面向对象-static、静态变量、静态方法、静态块、单例类
static可以修饰哪些成员 成员变量---可以修饰 构造方法---不可以 方法---可以修饰 初始化块---可以修饰 内部类(包括接口.枚举)---可以修饰 总的来说:静态成员不能访问非静态成员 静 ...
- 设计模式(java) 单例模式 单例类
·单例类 单实例类,就是这个类只能创建一个对象,保证了对象实例的唯一性. 1.单例模式( Singleton Pattern) 是一个比较简单的模式, 其定义如下:Ensure a class has ...
随机推荐
- Linux进程通信----匿名管道
Linux进程通信中最为简单的方式是匿名管道 匿名管道的创建需要用到pipe函数,pipe函数参数为一个数组表示的文件描述字.这个数组有两个文件描 述字,第一个是用于读数据的文件描述符第二个是用于写数 ...
- 通过项目逐步深入了解Mybatis<三>
Mybatis 高级知识 安排:对订单商品数据模型进行分析 订单商品数据模型 数据模型分析思路: 1.每张表记录的数据内容(分模块对每张表记录的内容进行熟悉,相当于学习系统需求的过程) 2.每张表重要 ...
- 为啥NSString的属性要用copy而不用retain
之前学习生活中,知道NSString的属性要用copy而不用retain,可是不知道为啥,这两天我研究了一下,然后最终明确了. 详细原因是由于用copy比用retain安全,当是NSString的时候 ...
- 在Swift中使用遗留的C API
Swift的类型系统的设计目的在于简化我们的生活,为此它强制用户遵守严格的代码规范来达到这一点.毫无疑问这是一件大好事,它鼓励程序员们编写 更好更正确的代码.然而,当Swift与历史遗留的代码库.特别 ...
- Hyperion Essbase BusinessRule 函数学习--2
@AVG Returns the average of all values in expList. [返回表达式列表的平均值] Syntax @AVG (SKIPNONE | SKIPMISSING ...
- Linux SSH 远程操作与传送文件
操作系统:centos 6.5 x64 一.远程连接:在进行linux 的 ssh远程操作前,一定要确认linux 是否安装了 openssh-clients,为了方便起见,一般用yum安装即可:# ...
- smaba服务的搭建
一. samba配置1. 什么是sambaSamba服务类似于windows上的共享功能,可以实现在Linux上共享文件,windows上访问,当然在Linux上也可以访问到.是一种在局域网上共享文件 ...
- 嵌套iframe中的HTML的文档解析类型
问题:页面整个刷新时,IE11输入框显示的宽度和高度正常,对页面中的iframe部分刷新时,IE11输入框的宽度和高度就变小了. 原因:网页的头部定义了文档类型<!DOCTYPE html> ...
- Java之可变参数
Java中支持可变参数 意思就是:参数的个数可以根据需要写,你可以写1个.2个.3个....他们都被保存到一个参数的数组中. 但是这些参有一些约束:他们必须是同类型的,比如都是String字符串类型. ...
- RtlInitUnicodeString、IoCreateDevice、IoCreateSymbolicLink、IoDeleteDevice 四个 API 驱动函数的使用
要解释"驱动对象",就得先从 DriverEntry() 说起: 做过C语言开发的都知道程序是从 main() 函数开始执行.在进行 Windows 驱动程序开发的时候没有 mai ...