intrusive_ptr源码分析

【BOOST C++容器专题03】【07】Boost.Intrusive Boost.Intrusive 是一个特别适合在高性能程序中使用的库。该库提供了创建侵入式容器的工具。这些容器替换了标准库中的已知容器。它们的缺点是它们不能像 std::list 或 std::set 那样容易使用。 阅读详情

intrusive_ptr是一个侵入式的引用计数型智能指针,它可以用于以下两种情形:

  • 对内存占用要求非常严格,要求必须与原始指针一样
  • 现存代码已经有了引用计数机制管理的对象

boost库不推荐使用intrusive_ptr,因为shared_ptr已经非常强大且灵活,工作足够好,可以满足绝大部分的需要。

下面来看一下intrusive的源码:

template<class T> class intrusive_ptr
{
private:
    typedef intrusive_ptr this_type;
public:
    typedef T element_type;

    intrusive_ptr() BOOST_NOEXCEPT : px( 0 )
    {
    }

    intrusive_ptr( T * p, bool add_ref = true ): px( p )
    {
        if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );
    }

    intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )
    {
        if( px != 0 ) intrusive_ptr_add_ref( px );
    }

    ~intrusive_ptr()
    {
        if( px != 0 ) intrusive_ptr_release( px );
    }

    // Move support
    //支持C++11移动构造,此处省略

    intrusive_ptr & operator=(intrusive_ptr const & rhs)
    {
        this_type(rhs).swap(*this);
        return *this;
    }

    intrusive_ptr & operator=(T * rhs)
    {
        this_type(rhs).swap(*this);
        return *this;
    }

    void reset() BOOST_NOEXCEPT
    {
        this_type().swap( *this );
    }

    void reset( T * rhs )
    {
        this_type( rhs ).swap( *this );
    }

    T * get() const BOOST_NOEXCEPT
    {
        return px;
    }

    T & operator*() const
    {
        BOOST_ASSERT( px != 0 );
        return *px;
    }

    T * operator->() const
    {
        BOOST_ASSERT( px != 0 );
        return px;
    }

// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>

    void swap(intrusive_ptr & rhs) BOOST_NOEXCEPT
    {
        T * tmp = px;
        px = rhs.px;
        rhs.px = tmp;
    }

private:

    T * px;
};

呵呵,非常简单,就是这么一点。但是我们发现,intrusive_ptr的构造析构等函数中,都使用了所管理的指针,以其作为参数执行某个函数。但实际上,这些函数是没有定义的。需要我们自己定义。

因为这几个函数的源码是这样的:

template< typename DerivedT, typename CounterPolicyT >
void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
template< typename DerivedT, typename CounterPolicyT >
void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;

呵,只有声明。

所以我们在使用intrusive_ptr是要自己提供引用计数,这就叫侵入式。我们可以在要管理的对象内部使用友元函数来实现上面那两个函数,执行计数器的加或减。但是通常我们会采用继承的方式实现,实现一个引用计数器基类,提供intrusive_ptr_add_ref()和intrusive_ptr_release()两个函数,然后继承它即可。

示例代码如下:

#include <iostream>
#include <boost/intrusive_ptr.hpp>

class reference_counter {
  int ref_count_;
public:
    reference_counter() : ref_count_(0) {}

    virtual ~reference_counter() {}

    friend void intrusive_ptr_add_ref(reference_counter *p) { 
      ++p->ref_count_;
    }   

    friend void intrusive_ptr_release(reference_counter *p) {
      if(--p->ref_count_)
        delete p;
    }   
    /*  error
    int use_count() {
        return ref_count_;
    }
    */
protected:
    reference_counter& operator=(const reference_counter&) {
    // 无操作
      return *this;
    }   
private:
    // 禁止复制构造函数
reference_counter(const reference_counter&); 
};

class some_class : public reference_counter {
public:
  some_class() {
    std::cout << "some_class::some_class()\n";
  }

  some_class(const some_class& other) {
    std::cout << "some_class(const some_class& other)\n";
  }

  ~some_class() {
    std::cout << "some_class::~some_class()\n";
  }
};

int main()
{
  std::cout << "Before start of scope\n";
  {
    boost::intrusive_ptr<some_class> p1(new some_class());
    boost::intrusive_ptr<some_class> p2(p1);
    //std::cout<<p2.use_count()<<std::endl;
  }
  std::cout << "After end of scope \n";
}

输出:

这里写图片描述

由于intrusive_ptr源码(上面已经给了)中不提供use_count()这个成员函数,所以我们也无法获得use_count值。

也许这样用你会觉得麻烦,不过实际上,boost中已经为我们实现了一个引用计数器的基类,我们使用intrusive_ptr时,继承该类就无需自己再费神了。

boost库中的引用计数基类是这样的:

template< typename DerivedT, typename CounterPolicyT >
class intrusive_ref_counter
{
private:
    //! Reference counter type
    typedef typename CounterPolicyT::type counter_type;
    //! Reference counter
    mutable counter_type m_ref_counter;

public:
    /*!
     * Default constructor
     *
     * \post <tt>use_count() == 0</tt>
     */
    intrusive_ref_counter() BOOST_NOEXCEPT : m_ref_counter(0)
    {
    }

    /*!
     * Copy constructor
     *
     * \post <tt>use_count() == 0</tt>
     */
    intrusive_ref_counter(intrusive_ref_counter const&) BOOST_NOEXCEPT : m_ref_counter(0)
    {
    }

    /*!
     * Assignment
     *
     * \post The reference counter is not modified after assignment
     */
    intrusive_ref_counter& operator= (intrusive_ref_counter const&) BOOST_NOEXCEPT { return *this; }

    /*!
     * \return The reference counter
     */
    unsigned int use_count() const BOOST_NOEXCEPT
    {
        return CounterPolicyT::load(m_ref_counter);
    }

protected:
    /*!
     * Destructor
     */
    BOOST_DEFAULTED_FUNCTION(~intrusive_ref_counter(), {})

    friend void intrusive_ptr_add_ref< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
    friend void intrusive_ptr_release< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
};

唉,上面这些就是intrusive_ptr的用法,有点蛋疼。不过却是让人感觉很叼的样子。侵入式的智能指针,相比shared_ptr,不需要虚函数的开销,确实性能强一些。

Boost库中的intrusive模块提供了许多高效的数据结构实现,其中avltree算法是一种基于AVL树实现的平衡二叉搜索树算法 Boost库中的intrusive模块提供了许多高效的数据结构实现,其中avltree算法是一种基于AVL树实现的平衡二叉搜索树算法。我们使用avl_set_base_hook将节点转换为可插入AVL树的类型,并添加了一个整型数据成员value_。可以看到,插入操作是通过调用MyTree对象的insert_unique()函数实现的,它将节点插入到树中。接着,需要定义一个节点类,该节点类需要包含两个指向自身类型的指针,以及用于查找的数据成员。这样就可以定义一个MyTree类型的平衡二叉搜索树了。 阅读详情

相关推荐

使用boost::intrusive::avl_set的测试程序

通过将包含特殊成员变量的自定义结构体作为元素类型,并使用boost::intrusive::avl_set进行管理,我们可以实现快速的插入、查找和删除操作。为了将MyElement类型的对象插入到boost::intrusive::avl_set容器中,我们将member_hook作为MyElement的一个成员变量。接下来,我们定义一个自定义的结构体作为元素类型,并使用boost::intrusive::avl_set作为容器类型。使用boost::intrusive::avl_set的测试程序。

HackMasterX的博客 224

侵入式容器 Boost.Intrusive

Boost.Intrusive 是一个很有意思的实现,里面实现了很多侵入式容器,在特定环境下,可以大大提升性能。 首先我们得理解什么是侵入式,什么是非侵入式。普遍,我们认为std的容器,比如std::list都是非侵入式的。这是因为对于任何一个(支持复制或者移动的)类型T,我们都可以定义std::list<T>。当往std::list里插入一个元素时,它会分配一个节点,这个节点的结构类似于下面这个: struct Node { T data; Node* prev;

一面之媛 2917

使用boost库中的intrusive模块提供的member_value_traits类可以方便地为用户定义的类型添加intrusive容器支持

在上述示例程序中,通过定义名为EmployeeTraits的traits类,使用name成员变量作为唯一索引进行标识,从而支持intrusive容器的操作。使用boost库中的intrusive模块提供的member_value_traits类可以方便地为用户定义的类型添加intrusive容器支持。使用member_value_traits类定义名为EmployeeTraits的traits类,将Employee类中的name成员变量作为唯一索引进行标识。遍历集合并输出每个员工的姓名和年龄。

2301_79326559的博客 159

boost::intrusive_ptr的用法

链接:https://www.jianshu.com/p/dd9701219b27。商业转载请联系作者获得授权,非商业转载请注明出处。作者:JasonLiThirty。

INGNIGHT的专栏 768

使用boost::intrusive实现循环链表算法的测试程序

在上面的代码中,我们使用circular_list_algorithms定义了一个算法类,用于操作循环链表。然后,我们初始化第一个节点n1,并通过link_after方法依次将n2、n3插入n1后面,形成一个循环链表。循环链表是一种特殊的链表,首尾节点可以相互连接,形成一个环状结构。其中,list_base_hook是boost::intrusive提供的节点基类,用于将节点插入链表中。最后,通过begin和end方法可以获取到链表的起始迭代器和结束迭代器,并使用循环遍历输出每一个节点的数据成员。

BUG?不存在的! 224

Boost Intrusive库中bucket_traits的使用示例

然后,我们使用MySet定义一个boost::intrusive::unordered_set类型的容器,并使用bucket_traits指定其桶的管理方式。其中,bucket_traits是一个非常有用的工具,可以在hash表等容器中分配和管理桶。可以看到,使用bucket_traits可以很方便地管理boost::intrusive::unordered_set等容器中的桶,这在实现基于intrusive容器的高效数据结构时非常有用。

BUG?不存在的! 121

Boost内存管理总结(scoped_ptr、unique_ptr、shared_ptr、weak_ptr、intrusive_ptr、pool、object_pool、singleton_pool)

内存管理总结1 简要介绍2 思维导图 1 简要介绍 Boost的内存管理库,包含两部分内容,分别是smart_ptr库和pool库,其中我们熟知的shared_ptr、unique_ptr、weak_ptr早已在2011年引入C++11标准。 smart_ptr库包含scoped_ptr、unique_ptr、shared_ptr、weak_ptr、intrusive_ptr pool库包含pool、object_pool、singleton_pool 2 思维导图 下面是Boost中内存管理思维图,包

我爱加菲猫 594

双击文件夹弹窗“找不到应用程序”,但是右键点击打开可以

此电脑、回收站、c、d、f盘、控制面板、任意文件夹等都没有办法双击打开。 右键中包含“使用filemanager打开”,是由于FileManager卸载残留导致的。 懒人专用附件 下载解压上面附件,双击导入可以清理FileManager软件残留 参考: 双击此电脑出现找不到应用程序,但是右键点击可以-其他-优快云问答https://ask.csdn.net/questions/7631439 电脑上的文件夹双击都提示找不到应用程序,但是右击打开就能打开,该怎么解决? - 知乎 (z

webmasterqpwou的博客 1万+

boost::intrusive_ptr VS boost::shared_ptr

看MongoDB源码,发现里面有用这种诡异智能指针的,以前没见过,学习了。原文地址 转载于:https://www.cnblogs.com/codingmylife/archive/2012/11/19/2777435.html

weixin_30945039的博客 148

免费升级哨兵2号分辨率!用SRCNN深度学习模型实现10米→2.5米超分重建

本文详细介绍了如何利用SRCNN深度学习模型,将哨兵2号遥感影像的分辨率从10米免费提升至2.5米。文章提供了从数据准备、模型训练到部署应用的全流程实战指南,旨在通过AI应用技术,为农业监测、城市规划等领域提供更高精度的影像数据支持。

coffee的博客 523

Ubuntu22.04中通过conda快速部署PyTorch开发环境(CPU/GPU双版本实战)

本文详细介绍了在Ubuntu22.04系统中,如何利用Conda高效部署PyTorch开发环境。文章分别提供了CPU与GPU双版本的实战教程,涵盖环境创建、镜像加速、版本匹配及深度验证等关键步骤,旨在帮助开发者快速搭建稳定、兼容的深度学习环境,从而专注于模型开发。

rose2的博客 556

caffe2源码分析之core第一篇----base

有一些内容参考了下面这篇博客,在此表示感谢。 https://www.cnblogs.com/jicanghai/p/9689726.html

浪子荆的博客 392

【毕设课设】基于YOLO v3与LSTM的水位智能识别系统(附完整源码+数据集)

本文详细介绍了基于YOLO v3与LSTM的水位智能识别系统的完整实现方案。该系统通过YOLO v3精准定位水位尺数字,结合LSTM-OCR进行序列识别,并融合霍夫变换检测刻度线,实现高精度水位自动读取。项目提供了从环境搭建、模型训练到集成部署的全流程指南,并附有完整源码和数据集,是理想的毕设课设实战项目。

php55的博客 609

[Pytorch 源码阅读] —— Tensor C++相关实现

文章目录版本介绍概念介绍源码分析intrusive_ptr 类TensorImpl 类StorageImpl 类总结 版本介绍 因为 Pytorch 版本迭代还是蛮快的,这里给出我源码阅读的版本及 commit 号以供参考。 master 分支,commit 号: 047925dac1c07a0ad2c86c281fac5610b084d1bd 概念介绍 Tensor 是 Pytorch 核心的数据结构,使用过 pytorch 的同学想必都不会陌生,它可以包含 scalar type 的数据(例如 floa

Chris_zhangrx的博客 5432

NetApp 7-mode初始化详解(原AGGR重建)及注意事项

没想到有生之年还能再写个7-mode的文章,上次接触可能已将近十年,本次恰巧碰到这个机会,边学习边整理,整整一天时间,碰到了不少坑,作为记录。

RaySun的技术Blog 2752

C++中const和指针*的组合问题

今天在复习> 章节7.3的时候想到以前做的一个题,const和指针运算符*的若干种组合的合法性和意义问题,有点混淆,所以写了一个测试代码来验证一下,简单明了,一目了然。如果有什么遗漏的话欢迎指出。 首先是在Ubuntu14.04.1下用gcc 4.8.4编译运行的结果,编译器报错信息都附加在对应语句后面的注释里 /* * Note : Test for the combinations of

theColdOne的专栏 1081

boost::intrusive_ptr为什么叫做倾入指针

具体来说,boost::intrusive_ptr需要对象类型提供一个自增函数(通常是通过模板参数传递给boost::intrusive_ptr的),这个自增函数负责管理引用计数。与std::shared_ptr和std::weak_ptr不同,boost::intrusive_ptr不管理对象的生命周期,而是依赖于对象的自增函数来管理其引用计数。使用方法:boost::intrusive_ptr的使用方法类似于std::shared_ptr,但需要手动管理对象的自增函数。当引用计数为0时,对象被释放。

王尚权 qq:2515162716 597

[QMT量化交易小白入门]-四十九、中小盘策略是否还有未来,市值再平衡策略,年化收益率124%

该策略旨在通过定期再平衡持仓,保持投资组合中股票数量恒定(),并优先持有市值较小的股票。具体来说,策略每两天(period = 2)进行一次再平衡,根据当前市值对持仓进行调整,以实现微盘股的投资目标。中小市值策略对资金量要求有限制,资金量太大由于流动性不足,滑点可能较大,资金量太小,可能不能达到10-20只持仓,来分散风险,10-100w可能是比较理想的,后续可以根据波动率动态调仓,或波动率大于一定值时触发再平衡加入ROE或其他财务指标,或者研发投入强度大的专精特新企业,进行组合优化。

木头大左的博客 1184

C++智能指针 intrusive_ptr

intrusive_ptr: intrusive_ptr是一个侵入式的引用计数型指针,它可以用于以下两种情形: 【1】对内存占用的要求非常严格,要求必须与原始指针一样; 【2】现存代码已经有了引用计数机制管理的对象 boost::intrusive_ptr一种“侵入式”的引用计数指针,它实际并不提供引用计数功能,而是要求被存储的对象自己实现引用计数功能,并提供intrusive_ptr

晴天的专栏 5322

利用Python实现Springer文献关键词爬虫

🔧 如何分析Springer的搜索结果HTML结构🕷️ 编写高性能异步爬虫抓取论文元数据📊 使用Pandas导出Excel🧠 如何处理作者、摘要、DOI等字段🔄 如何优化爬虫稳定性与可扩展性。

2201_76125261的博客 415

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Boost练习3——内存管理之智能指针

一、smart_ptr库概述 new、delete以及指针的不恰当运用是c++中造成资源获取、释放问题的根源,智能指针可以在退出作用域时,不管是正常流程离开或是因异常离开,总调用delete来析构在堆上动态分配的对象。 boost.smart_ptr库提供了六种智能指针,shared_ptr、weak_ptr、scoped_ptr、scoped_array、shared_array、intru...

xiaoxiaoyusheng2012的专栏 666

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

智能指针 intrusive_ptr

intrusive_ptr:  intrusive_ptr是一个侵入式的引用计数型指针,它可以用于以下两种情形:  【1】对内存占用的要求非常严格,要求必须与原始指针一样;  【2】现存代码已经有了引用计数机制管理的对象。

mmzsyx的专栏 1619

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

侵入式容器及Boost.Intrusive

非侵入式容器存储的是对象的拷贝,而不是传递给容器的原始对象,例如STL容器,当插入对象时,需要申请内存存放拷贝的对象,而对象在容器内的关系是由容器本身数据结构来维护的,内容内对象本事并不知道容器信息。侵入式容器直接存储传递给容器的原始对象,而不是对象的拷贝。对象内部维护和容器之间的关系。

doingli的博客 7595

Boost库基础-智能指针(intrusive_ptr)

intrusive_ptr intrusive_ptr是一种引用计数型智能指针,与之前介绍的scoped_ptr、shared_ptr不同,需要额外增加一些的代码才能使用。 如果现存代码已经有了引用计数机制管理的对象,那么intrusive_ptr是一个非常好的选择,可以包装已有对象从而得到与shared_ptr类似的智能指针。 因为他是引用计数类型指针,所以接口与shared_pt...

希望能帮助大家,希望大家多多支持,你们的支持是我前进的动力。 1978

C++ | boost库之智能指针

一、RAII机制 RAII机制在之前的文章中有讲解,具体可以查看C++ 内存管理这篇文章。 二、智能指针 向 C ++ 引入异常机制后,智能指针由一种技巧升级为一种非常重要的技术,因为如果没有智能指针,程序员必须保证 new 对象能在正确的时机 delete ,必须到处编写异常捕获代码以释放资源,而智能指针则可以在退出作用域时(无论是因正常流程离开还是因异常离开)总调用 delete 来析构在堆上动态分配的对象。 1.C++98下auto_ptr a...

该用户还没想到好的昵称的博客 1358
上一篇: shared_ptr的理解和注意事项
下一篇: 有关卡特兰数的面试题
FreeeLinux
博客等级 码龄11年 421粉丝 356原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值