boost序列化单例3

news2024/10/6 20:27:54

源码见文章底部。

class singleton 声明了一个静态引用 static T & m_instance;
这个静态引用是用来干嘛的呢?注意到该文件末尾有如下代码:

template<class T>
T & singleton< T >::m_instance = singleton< T >::get_instance();

读到这里应该大概能理解了,该引用只是为了使用static的特性,该全局对象在程序初始化之前就进行了实例化了对象。

单例函数get_instance()方位属性为private。内部有如下定义 class singleton_wrapper : public T {};将T的构造函数保护了起来。先将静态成员赋值然后在堆中构造对象,静态成员指向他。

is_destroyed()主要作用是对生命周期做控制管理。

template <class T> static void use(T const *) 只是为了消除未初始化的警告,可参考另一工具类

boost::template <typename... Ts>void ignore_unused()的使用。最后调用构造生成实例对象并返回其引用。

     // refer to instance, causing it to be instantiated (and
     // initialized at startup on working compilers)
     BOOST_ASSERT(! is_destroyed());

     // note that the following is absolutely essential.
     // commenting out this statement will cause compilers to fail to
     // construct the instance at pre-execution time.  This would prevent
     // our usage/implementation of "locking" and introduce uncertainty into
     // the sequence of object initializaition.
     use(& m_instance);

     if (!t)
         t = new singleton_wrapper;
     return static_cast<T &>(*t);

class singleton的析构函数负责清理资源。
下面的代码为测试简单的简单的静态对象单例模式与boost::serialization::singleton的区别

#include <boost/serialization/singleton.hpp>
#include <iostream>
template<typename T>
class singleton_test
{
private:
	T tt;
public:
	T& get_instance() { return tt; }
};
 
class TEST_CLASS1
{
public:
	TEST_CLASS1() { std::cout << __FUNCTION__ << std::endl; }
	~TEST_CLASS1(){ std::cout << __FUNCTION__ << std::endl; }
 
	void print() { std::cout << "hello, im TEST_CLASS1" << std::endl; }
};
 
class TEST_CLASS2
{
public:
	TEST_CLASS2() { std::cout << __FUNCTION__ << std::endl; }
	~TEST_CLASS2() { std::cout << __FUNCTION__ << std::endl; }
 
	void print() { std::cout << "hello, im TEST_CLASS2" << std::endl; }
};
 
int main()
{
	std::cout << "begin main:" << std::endl;
	boost::serialization::singleton<TEST_CLASS2> t2;
	singleton_test<TEST_CLASS1> t1;
 
 
	t1.get_instance().print();
	t2.get_mutable_instance().print();
 
	std::cout << "end main:" << std::endl;
}

测试结果如图:
在这里插入图片描述
在这里插入图片描述
可知boost库的单件在程序入口点(main)之前已经完成构造。而两者析构顺序与声明顺序相关(逆序)。

boost库的单件源码(版本boost_1_66_0)

template <class T>
class singleton : public singleton_module
{
private:
    static T & m_instance;
    // include this to provoke instantiation at pre-execution time
    static void use(T const *) {}
    static T & get_instance() {
        // use a wrapper so that types T with protected constructors
        // can be used
        class singleton_wrapper : public T {};
 
        // Use a heap-allocated instance to work around static variable
        // destruction order issues: this inner singleton_wrapper<>
        // instance may be destructed before the singleton<> instance.
        // Using a 'dumb' static variable lets us precisely choose the
        // time destructor is invoked.
        static singleton_wrapper *t = 0;
 
        // refer to instance, causing it to be instantiated (and
        // initialized at startup on working compilers)
        BOOST_ASSERT(! is_destroyed());
 
        // note that the following is absolutely essential.
        // commenting out this statement will cause compilers to fail to
        // construct the instance at pre-execution time.  This would prevent
        // our usage/implementation of "locking" and introduce uncertainty into
        // the sequence of object initializaition.
        use(& m_instance);
 
        if (!t)
            t = new singleton_wrapper;
        return static_cast<T &>(*t);
    }
    static bool & get_is_destroyed(){
        static bool is_destroyed;
        return is_destroyed;
    }
 
public:
    BOOST_DLLEXPORT static T & get_mutable_instance(){
        BOOST_ASSERT(! is_locked());
        return get_instance();
    }
    BOOST_DLLEXPORT static const T & get_const_instance(){
        return get_instance();
    }
    BOOST_DLLEXPORT static bool is_destroyed(){
        return get_is_destroyed();
    }
    BOOST_DLLEXPORT singleton(){
        get_is_destroyed() = false;
    }
    BOOST_DLLEXPORT ~singleton() {
        if (!get_is_destroyed()) {
            delete &(get_instance());
        }
        get_is_destroyed() = true;
    }
};
 
template<class T>
T & singleton< T >::m_instance = singleton< T >::get_instance();
 
} // namespace serialization
} /

https://blog.csdn.net/u012508160/article/details/79127729

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1044895.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第8讲:Vue 对象的生命周期

Vue 实例在创建时有一系列初始化步骤——例如&#xff0c;它需要建立数据观察&#xff0c;编译模板&#xff0c;创 建必要的数据绑定。在此过程中&#xff0c;它也将调用一些生命周期钩子&#xff0c;给自定义逻辑提供运行机 会。 生命周期图示 Vue 对象的生命周期函数 1、bef…

04 Zookeeper集群详解

上一篇&#xff1a;03-Zookeeper客户端使用 Zookeeper 集群模式一共有三种类型的角色 Leader: 处理所有的事务请求&#xff08;写请求&#xff09;&#xff0c;可以处理读请求&#xff0c;集群中只能有一个LeaderFollower&#xff1a;只能处理读请求&#xff0c;同时作为 Le…

TCP连接的三次握手与四次挥手【重点】

TCP的运输连接管理概述 TCP是面向连接的协议&#xff0c;它基于运输连接来传送TCP报文段 TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程 TCP运输连接有以下三个阶段 TCP的运输连接管理就是使运输连接的建立和释放都能正常的进行 TCP建立连接的三次握手&a…

ChatGPT 在机器学习中的应用

办公室里一个机器人坐在人类旁边&#xff0c;Artstation 上的流行趋势&#xff0c;美丽的色彩&#xff0c;4k&#xff0c;充满活力&#xff0c;蓝色和黄色&#xff0c; DreamStudio出品 一、介绍 大家都知道ChatGPT。它在解释机器学习和深度学习概念方面也非常高效&#xff0c;…

springboot 简单配置mongodb多数据源

准备工作&#xff1a; 本地mongodb一个创建两个数据库 student 和 student-two 所需jar包&#xff1a; # springboot基于的版本 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId>&l…

csdn未经允许将我的文章设置成vip收费

以前在csdn写了一些笔记&#xff0c;后来不用csdn了&#xff0c;想着留下这些笔记或多或少能帮助其他初学者&#xff0c;就没管它。结果csdn把文章设置成收费了&#xff0c;这个收费不是我本人弄的&#xff0c;是csdn弄的&#xff01;我现在只能把这些文章删除掉了。

ThreeJS-3D教学三:平移缩放+物体沿轨迹运动

我们在项目中会有一些这样的需求&#xff0c;我们可视化一个场景&#xff0c;需要俯视、平移、缩放&#xff0c;方便观察场景中的数据或者模型&#xff0c;之所以把这个案例拿出来 1、这是个很实用的需求&#xff0c;我相信很多人会用到 2、我自己认为在实际案例中我们可以学习…

高手必备!电脑剪辑视频的实用方法

随着数码时代的到来&#xff0c;越来越多的人开始使用电脑剪辑视频。电脑剪辑视频不仅可以为日常生活留下美好回忆&#xff0c;还可以为专业人士提供更多的创作可能性。在本文中&#xff0c;我们将介绍两种电脑剪辑视频的方法&#xff0c;不需要专业技能&#xff0c;只需要一台…

精细高效 智慧公厕为城市公共厕所联网管理装上“智慧中枢”

近年来&#xff0c;随着城市化进程的加速&#xff0c;城市公共设施的更新与改进也成为各地的重要任务之一。而其中&#xff0c;城市公共厕所的建设和管理更是备受关注。为了提高公厕的服务水平和城市形象&#xff0c;各地纷纷采取创新的智能化手段&#xff0c;将公厕与互联网技…

MT41K128M16JT DDR3寻址

MT41K128M16JT该DDR3共有27bit地址&#xff0c;分别如下&#xff1a; 因为DDR3控制器IP与DDR3的数据端口是128bit&#xff0c;而ddr3的物理宽度是16bit&#xff0c;所以ddr3写一次地址增加3。 ddr3控制器地址26–0&#xff0c;能访问到的最高地址是26-323。 ddr3控制器给出的地…

在线客服系统源码/在线对话聊天/多商户在线客服系统源码(可机器人自动聊天/支持app公众号网页H5)

源码介绍 在线客服系统源码/在线对话聊天/多商户在线客服系统源码&#xff0c;它是一款基于Web的在线客服系统&#xff0c;适用于实现企业与客户之间的在线沟通以及咨询服务。该系统支持多商户、无限座席&#xff0c;可以为多个企业提供在线客服服务&#xff0c;不受座席数量的…

跨境电商下半年如何布局,旺季销售策略全盘点,为火爆季节做准备

1.了解跨境电商市场趋势&#xff1a;在下半年旺季之前&#xff0c;了解目标市场的消费趋势、流行产品和购物偏好等因素非常重要。研究和分析市场数据&#xff0c;以及观察竞争对手的动向&#xff0c;可以帮助您更好地制定布局策略。 2.优化产品和供应链&#xff1a;确保您的产…

一文读懂云计算、云原生!

“上云”是一种大趋势。 根据Gartner的数据&#xff0c;未来云计算市场规模仍将保持20%以上的增长速度。到2025年&#xff0c;预计将有80%的企业会将其业务上云。 云的发展为何备受企业青睐&#xff1f;近年来火爆的云原生和云计算的区别到底是什么呢&#xff1f;为什么它如此…

工作流引擎笔记 20230927

现在需要一个管理数据业务流程配置功能。想到了workflow manage system/engine 概念调研 在工作流管理系统中&#xff0c;工作流引擎是核心组件&#xff0c;它负责驱动和执行定义好的工作流程。本文将详细介绍工作流引擎的关键特性、类型、与状态机的差异&#xff0c;以及设计…

Jmeter系列- 详解 CSV 数据文件设置

一、什么是csv文件 CSV文件&#xff1a;是指"逗号分隔值"&#xff08;Comma-Separated Values&#xff09;文件&#xff0c;它是一种简单的文件格式&#xff0c;用于存储表格数据&#xff0c;例如电子表格或数据库&#xff0c;可以用记事本和Excel打开&#xff0c;用…

《从零开始的Java世界》02面向对象(基础)

《从零开始的Java世界》系列主要讲解Javase部分&#xff0c;从最简单的程序设计到面向对象编程&#xff0c;再到异常处理、常用API的使用&#xff0c;最后到注解、反射&#xff0c;涵盖Java基础所需的所有知识点。学习者应该从学会如何使用&#xff0c;到知道其实现原理全方位式…

同为科技(TOWE)太阳能光伏直流电源浪涌保护器的产品应用

太阳能光伏发电是根据光生伏特效应原理&#xff0c;利用太阳电池将太阳光能直接转化为电能。实现方法是通过将太阳光转化为直流电&#xff0c;然后通过逆变器转换为交流电&#xff0c;以供家庭、企业和电网使用。太阳能光伏发电具有许多优点&#xff0c;例如环保、可再生、安全…

查看基站后台信息

查看基站后台信息 电脑配置固定ip: 192.168.1.99: 打开“网络和共享中心”&#xff0c;选择更改适配器设置&#xff1a; 右键“本地连接”&#xff0c;选择属性 基站网线直连电脑网口 Telnet 登录基站 打开dos窗口 windows键R”&#xff0c;输入cmd&#xff0c;点确定&…

TS中class类的基本使用

想要创建对象&#xff0c;必须要先定义类&#xff0c;所谓的类可以理解为对象的模型&#xff0c;程序中可以根据类创建所指定类型的对象。 一、使用class关键字定义类 class 类名 { } // 使用class关键字来定义一个类 class Person{}// 使用new关键字创建一个对象 const per …

新型基础设施:信息技术设施、融合基础设施和创新基础设施

新型基础设施主要包括信息技术设施、融合基础设施和创新基础设施三个方面。 信息基础设施包括哪些呢&#xff1f; 信息基础设施主要指基于新一代信息技术演化生成的基础设施。 1. 以5G、物联网、工业互联网、卫星互联网为代表的通信网络基础设施&#xff1b; 2. 以人工智能、…