(七)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库之单例类的更多相关文章

  1. muduo网络库源码学习————线程本地单例类封装

    muduo库中线程本地单例类封装代码是ThreadLocalSingleton.h 如下所示: //线程本地单例类封装 // Use of this source code is governed b ...

  2. c++:自己动手实现线程安全的c++单例类

    前段时间使用c++做项目开发,需要根据根据配置文件路径加载全局配置文件,并对外提供唯一访问点.面对这样一个需求,自然的就想到了使用单例模式来创建一个单例配置对象,供外部调用.一开始想使用boost中自 ...

  3. C++解析(27):数组、智能指针与单例类模板

    0.目录 1.数组类模板 1.1 类模板高效率求和 1.2 数组类模板 1.3 堆数组类模板 2.智能指针类模板 2.1 使用智能指针 2.2 智能指针类模板 3.单例类模板 3.1 实现单例模式 3 ...

  4. 设计模式——懒汉式单例类PK饿汉式单例类

    前言 我们都知道生活中好多小软件,有的支持多IP在线,有的仅仅局限于单个IP在线.为什么这样设计,在软件开发阶段就是,有需求就是发展.这就是软件开发的一个设计模式--懒汉式单例类和饿汉式单例类. 内容 ...

  5. java单例类/

    java单例类  一个类只能创建一个实例,那么这个类就是一个单例类 可以重写toString方法 输出想要输出的内容 可以重写equcal来比较想要比较的内容是否相等 对于final修饰的成员变量 一 ...

  6. iOS中编写单例类的心得

    单例 1.认识过的单例类有哪些: NSUserDefaults.NSNotificationCenter.NSFileManager.UIApplication 2.单例类 单例类某个类在代码编写时使 ...

  7. 如何防止JAVA反射对单例类的攻击?

    在我的上篇随笔中,我们知道了创建单例类有以下几种方式: (1).饿汉式; (2).懒汉式(.加同步锁的懒汉式.加双重校验锁的懒汉式.防止指令重排优化的懒汉式); (3).登记式单例模式; (4).静态 ...

  8. 0013 Java学习笔记-面向对象-static、静态变量、静态方法、静态块、单例类

    static可以修饰哪些成员 成员变量---可以修饰 构造方法---不可以 方法---可以修饰 初始化块---可以修饰 内部类(包括接口.枚举)---可以修饰 总的来说:静态成员不能访问非静态成员 静 ...

  9. 设计模式(java) 单例模式 单例类

    ·单例类 单实例类,就是这个类只能创建一个对象,保证了对象实例的唯一性. 1.单例模式( Singleton Pattern) 是一个比较简单的模式, 其定义如下:Ensure a class has ...

随机推荐

  1. C语言中long类型,int类型

    long类型表示long int,一般简写为long,注意long不表示long double.虽然有时候会有sizeof(long)=sizeof(int),long int与int是不同的: 16 ...

  2. web前端设计:JQuery MINI UI

    JQuery MINIUI 个人感觉用起来很爽,所以在此记录之,以后开发过程可能作为备选项.它能缩短开发时间,减少代码量,使开发者更专注于业务和服务端,轻松实现界面开发,带来绝佳的用户体验.在线下载地 ...

  3. SVN trunk、branch、tag的用法

    Subversion有一个很标准的目录结构,是这样的.比如项目是proj,svn地址为svn://proj/,那么标准的svn布局是svn://proj/|+-trunk+-branches+-tag ...

  4. 执行此安装程序之前,必须安装 32 位 Windows 映像处理组件(WIC)解决的方法

    我们在Windows Service 2003上安装 Microsoft .NET Framework4.0时常常出现以下的报错 执行此安装程序之前,必须安装 32 位 Windows 映像处理组件( ...

  5. 如何彻底解决jsp页面中文乱码及数据库乱码

    最近自己闲做一个小项目,搭建环境框架SSH+MySQL数据库,遇到一个问题:jsp页面中文显示乱码,数据库插入数据和更新数据时中文也显示乱码,后来在网上找了许多解决方法,还是折腾了两天才把问题解决,下 ...

  6. C#关于params的用法(使用数量可变的参数)

    有些方法需要传递个数不定的值进行运算.比如求最小值的方法.除了用容器外,还可以使用params来做 例子如下: using System; using System.Collections.Gener ...

  7. 浏览器渲染页面过程描述,DOM编程技巧以及重排和重绘。

    一.浏览器渲染页过程描述 1.浏览器解析html源码,然后创建一个DOM树. 在DOM树中,每一个HTML标签都有一个对应的节点(元素节点),并且每一个文本也都有一个对应的节点(文本节点). DOM树 ...

  8. 关于String字符串反转

    这是网上看到的一篇java面试题中的问题: 问题是: 如何将一个String字符串反转. String str = "1234567"; int length = str.leng ...

  9. (原创) C# List 找 Max 的 Index

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  10. stuts1:(Struts)Action类及其相关类

    org.apache.struts.action.Action类是Struts的心脏,也是客户请求和业务操作间的桥梁.每个Action类通常设计为代替客户完成某种操作.一旦正确的Action实例确定, ...