shared_ptr源码分析

《shared_ptr源码剖析》 本文将以Centos标准库为基础,剖析shared_ptr的源码,shared_ptr主要包含两个部分:shared_ptr_base.h和shared_ptr.h,虽然涉及的文件不多,但为了实现一套完备的内存托管方案出来,gcc还是设计很多类出来。且看如下图片,笔者将结合图片逐步为您剖析shared_ptr托管内存的原理和细节。1. shared_ptr结构和源码。 阅读详情

shared_ptr与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它实现的是引用技术型的智能指针,可以自由地被拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0时)它才删除包装的动态分配的对象。shared_ptr也可以安全地放到标准容器中,弥补了auto_ptr因为转移语义而不能把指针作为STL容器的缺陷。
 

源码分析

首先看shared_ptr类:

template<class T> class shared_ptr
{
private:

    // Borland 5.5.1 specific workaround
    typedef shared_ptr<T> this_type;

public:

    typedef typename boost::detail::sp_element< T >::type element_type;

    //构造一个空shared_ptr
    shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+
    {
    }

    //使用指针构造shared_ptr,该Y类型指针必须可以转换为T类型,Y类型可以和T类型一致
    template<class Y>   //参数不同意味着支持转换,Y类型需要能转换为T类型,比如base-derived
    explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
    {
        boost::detail::sp_pointer_construct( this, p, pn );    //为enable_shared_from_this类weak_this_成员初始化,下面会详述。
        /* 下面是它底层底层调用的函数,我直接注释在此处
        template< class T, class Y > 
        inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn )
        {
            boost::detail::shared_count( p ).swap( pn );
            boost::detail::sp_enable_shared_from_this( ppx, p, p );
        }
        */
    }

    //
    // Requirements: D's copy constructor must not throw
    //
    // shared_ptr will release p by calling d(p)
    //
    //指针、删除器
    template<class Y, class D> shared_ptr( Y * p, D d ): px( p ), pn( p, d )
    {
        boost::detail::sp_deleter_construct( this, p );
        /*同上,注释
        template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T > * ppx, Y * p )
        {
            boost::detail::sp_enable_shared_from_this( ppx, p, p );
        }
        */
    }

    // As above, but with allocator. A's copy constructor shall not throw.
    //指针、删除器、分配器
    template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
    {
        boost::detail::sp_deleter_construct( this, p );
    }

//  generated copy constructor, destructor are fine...
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
// ... except in C++0x, move disables the implicit copy   //除了在C++ 0x中,移动构造会遮蔽隐式拷贝构造
    shared_ptr( shared_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
    {
    }
#endif

    template<class Y>
    explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn ) // may throw
    {
        boost::detail::sp_assert_convertible< Y, T >();  //检测Y和T类型是否可以转换
        // it is now safe to copy r.px, as pn(r.pn) did not throw
        px = r.px;
    }

    template<class Y>
    shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag )   //不抛出异常的版本
    BOOST_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() )
    {
        if( !pn.empty() )
        {
            px = r.px;
        }
    }

    template<class Y>
    shared_ptr( shared_ptr<Y> const & r )    //使用shared_ptr构造
    BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
    {
        boost::detail::sp_assert_convertible< Y, T >();
    }

    //意思就是用p构造本shared_ptr,但是本shared_ptr和r共享引用计数,即便本shared_ptr调用reset,只要r不死,那本shared_ptr也不死。共享引用计数两方都可以加减引用计数。
    // aliasing
    template< class Y >
    shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
    {
    }

#ifndef BOOST_NO_AUTO_PTR
    //FIXME
    //注意这里用的auto_ptr的引用,并且没有调用auto_ptr的release函数,shared_count(r)中会调用
    //shared_ptr从一个auto_ptr获得指针的管理权,引用计数置位1,同时auto_ptr将自动失去管理权
    template<class Y>
    explicit shared_ptr( std::auto_ptr<Y> & r ): px(r.get()), pn()
    {
        boost::detail::sp_assert_convertible< Y, T >();

        Y * tmp = r.get();
        pn = boost::detail::shared_count( r );

        boost::detail::sp_deleter_construct( this, tmp );
    }


#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
    template< class Y, class D >
    shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn()
    {
        boost::detail::sp_assert_convertible< Y, T >();

        typename std::unique_ptr< Y, D >::pointer tmp = r.get();
        pn = boost::detail::shared_count( r );

        boost::detail::sp_deleter_construct( this, tmp );
    }
#endif

    // assignment
    shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT
    {
        this_type(r).swap(*this);
        return *this;
    }

#ifndef BOOST_NO_AUTO_PTR
    template<class Y>
    shared_ptr & operator=( std::auto_ptr<Y> & r )
    {
        this_type( r ).swap( *this );
        return *this;
    }

#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
    template<class Y>
    shared_ptr & operator=( std::auto_ptr<Y> && r )
    {
        this_type( static_cast< std::auto_ptr<Y> && >( r ) ).swap( *this );
        return *this;
    }
#endif // BOOST_NO_AUTO_PTR

#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
    //支持C++11的unique_ptr
    template<class Y, class D>
    shared_ptr & operator=( std::unique_ptr<Y, D> && r )
    {
        this_type( static_cast< std::unique_ptr<Y, D> && >( r ) ).swap(*this);
        return *this;
    }
#endif

// Move support
    shared_ptr( shared_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn()
    {
        pn.swap( r.pn );
        r.px = 0;
    }

    template<class Y>
    shared_ptr( shared_ptr<Y> && r )    //C++11的移动构造
    BOOST_NOEXCEPT : px( r.px ), pn()
    {
        boost::detail::sp_assert_convertible< Y, T >();

        pn.swap( r.pn );
        r.px = 0;
    }

    shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT
    {
        this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
        return *this;
    }

    //仅重置
    void reset() BOOST_NOEXCEPT // never throws in 1.30+
    {
        this_type().swap(*this);   //666,直接构造一个null对象和this交换
    }

    //重置为p
    template<class Y> void reset( Y * p ) // Y must be complete
    {
        BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
        this_type( p ).swap( *this );
    }

    //这里省略reset的另外两个版本:(1)重置为p指针,带有一个删除器。(2)重置为p指针,带有删除器和内存分配器。

    //共享引用计数的模式
    template<class Y> void reset( shared_ptr<Y> const & r, element_type * p )
    {
        this_type( r, p ).swap( *this );
    }

    // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
    typename boost::detail::sp_dereference< T >::type operator* () const
    {
        BOOST_ASSERT( px != 0 );
        return *px;
    }

    // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
    typename boost::detail::sp_member_access< T >::type operator-> () const 
    {
        BOOST_ASSERT( px != 0 );
        return px;
    }

    // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
    typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const
    {
        BOOST_ASSERT( px != 0 );
        BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );

        return px[ i ];
    }

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

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

    //返回引用计数是否为1
    bool unique() const BOOST_NOEXCEPT
    {
        return pn.unique();
    }
    //返回引用计数
    long use_count() const BOOST_NOEXCEPT
    {
        return pn.use_count();
    }
    //异常安全的swap,可配合no-member swap函数
    void swap( shared_ptr & other ) BOOST_NOEXCEPT
    {
        std::swap(px, other.px);
        pn.swap(other.pn);
    }
    //可以理解为是不是要早死吗?
    template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
    {
        return pn < rhs.pn;
    }

    template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
    {
        return pn < rhs.pn;
    }

    //用于内部获取删除器,如果没有返回空,即非删除器构造
    void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_NOEXCEPT
    {
        return pn.get_deleter( ti );
    }

    void * _internal_get_untyped_deleter() const BOOST_NOEXCEPT
    {
        return pn.get_untyped_deleter();
    }
    //成员函数比较是否相等,shared_ptr也提供非成员函数比较的方式
    bool _internal_equiv( shared_ptr const & r ) const BOOST_NOEXCEPT
    {
        return px == r.px && pn == r.pn;
    }

// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends. (Matthew Langston)

private:

    template<class Y> friend class shared_ptr;
    template<class Y> friend class weak_ptr;

    element_type * px;                 // contained pointer
    boost::detail::shared_count pn;    // reference counter

};  // shared_ptr

上面就是shared_ptr的大致源码,我把一些过多的预处理宏,都去掉了。还有过多的C++11的东西,不过仍然保留了部分如移动构造,以及unique_ptr。

shared_ptr可以由一个普通指针构造,它也可以在类内部使用shared_from_this构造(与构造函数那一句有关,稍后分析),甚至auto_ptr或是unique_ptr也都可以。

下面来看shared_ptr的构造函数中奇怪的那一句:

template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn() // px是被管理的对象指针;pn是引用计数器,shared_ptr内部管理
{
  boost::detail::sp_pointer_construct( this, p, pn ); // 开始构造
}

template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn )
{   //至于为什么用swap来构造pn,我认为这是为了异常安全,因为pn构造函数中用到了new
    boost::detail::shared_count( p ).swap( pn ); // 创建引用计数器,swap等价于赋值给pn
    boost::detail::sp_enable_shared_from_this( ppx, p, p );
}

// sp_enable_shared_from_this 模板重载了多个,针对被管理的是enable_shared_from_this的派生类的对象时自动选择执行这个函数
template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )  //注第三个参数类型是enable_shared_from_this,使用基类指针指向派生类
{
    if( pe != 0 )
    {
        pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
    }
}

template<class T> class enable_shared_from_this
{
public:
   // 获取指向自身的智能指针,weak_ptr作为观察者能够判断指针是否已经释放
    shared_ptr<T> shared_from_this()
    {
        shared_ptr<T> p( weak_this_ );
        BOOST_ASSERT( p.get() == this ); // 如果指针已经释放,那么这里就会报错了
        return p;
    }

    shared_ptr<T const> shared_from_this() const
    {
        shared_ptr<T const> p( weak_this_ );
        BOOST_ASSERT( p.get() == this );
        return p;
    }

public:

    // 派生对象内部保存一份私有的weak_ptr,用来获取指向自身(this)的智能指针
    // Note: invoked automatically by shared_ptr; do not call
    template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
    {
        if( weak_this_.expired() )
        {
            weak_this_ = shared_ptr<T>( *ppx, py );  //这里就构造了一个weak_ptr,且其目前监视的对象引用计数为1,
           //调用shread_ptr的shared_ptr( shared_ptr<Y> const & r, element_type * p ),使用p构造一个shared_ptr和r共享引用计数,而r正是我们最初要构造的shared_ptr的this指针,p即我们最初传给shared_ptr的参数
           //所以这里相当于赋值该weak_ptr,以后该weak_ptr就监视本shared_ptr了
           //为什么说赋值,因为weak_count已经默认初始化过了,只不过weak_count之前为0,详见enable_shared_from_this类构造函数
        }
    }
private:
    mutable weak_ptr<T> weak_this_;
};

上面这一大堆起了什么作用呢?答案就是初始化enable_shared_from_this相关的引用计数。有了这个我们就可以这样用了:

class Y: public boost::enable_shared_from_this<Y>
{
public:

    boost::shared_ptr<Y> f()
    {
        return shared_from_this();
    }
};

// 正确的使用方法
boost::shared_ptr<Y> p(new Y);
boost::shared_ptr<Y> q = p->f();  

// 错误的使用方法,因为Y的成员weak_ptr 根本就没有得到初始化,必须先使用shared_ptr管理class才可以
Y  yy;
boost::shared_ptr<Y> q = yy.f();

好了,构造函数就分析到这里,至于sp_deleter_construct()函数,和这个流程一致,只不过加了个删除器而已。
 

操作函数

shared_ptr与scoped_ptr同样是用于管理new动态分配对象的智能指针,因此功能上有很多相似之处:它们都重载了*和->操作符以模仿原始指针的行为,提供隐式bool类型转换以判断指针的有效性,get可以得到原始指针(return px),并且没有提供指针算数操作。

例如:

shared_ptr<int> spi(new int);
assert(spi);
*spi = 253;
shared_ptr<string> sps(new string("smart"));
assert(sps->size() == 5);

shared_ptr有多种形式构造函数,应用于各种可能的情形:

  • 无参的shared_ptr()创建一个持有空指针的shared_ptr;
  • shared_ptr(Y* p)获得指向类型T的指针p的管理权,同时引用计数置为1.这个构造函数要求Y类型必须能够转换为T类型;
  • shared_ptr(shared_ptr const & r)从另外一个shared_ptr获得指针的管理权,同时引用计数加1,结果是两个shared_ptr共享一个指针的管理权;
  • shared_ptr(std::auto_ptr< Y> &r)从另外一个auto_ptr获得指针的管理权,引用计数置为1,同时auto_ptr自动失去管理权;
  • operator=赋值操作符可以从另外一个shared_ptr或auto_ptr获得指针的管理权,其行为同构造函数。
  • shared_ptr(Y *p, D d)行为类似shared_ptr(Y *p),但是用参数d指定了析构时定值删除器,而不是简单的delete。

shared_ptr的reset()函数与scoped_ptr也不尽相同。它的作用是将引用计数减1,停止对指针的共享,除非引用计数为0,否则不会发生删除操作。带参数的reset()则是类似相同形式的构造函数,原指针引用计数减1的同时改为管理另一个指针。

shared_ptr有两个专门的函数检查引用计数。unique()检查shared_ptr是指针唯一所有者返回true,use_count()返回当前引用计数。use_count()应该仅用于测试或调试,它不提供高效的操作,而且有可能是不可用的(极少数情形)。

shared_ptr还支持比较运算,可以测试两个shared_ptr的相等或不相等,比较基于内部保存的指针,相当于a.get()==b.get()。shared_ptr还可以使用operator<比较大小。同样基于内部保存的指针,但不提供除operator<之外的比较操作符,这使得shared_ptr可以被用于标准关联容器(set和map)。

**shared_ptr的类型转换不能使用static_cast之流,只能使用shared_ptr自己提供的转型函数:static_pointer_cast()、const_pointer_cast()、dynamic_pointer_cast()和reinterpret_cast()函数,它们转型后棵正确返回shared_ptr类型。

此外,shared_ptr还支持流输出操作符operator<<,输出内部指针值,方便调试。

相关代码如下:

template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
{
    return a.owner_before( b );
}

template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_NOEXCEPT
{
    a.swap(b);
}

template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
{
    (void) static_cast< T* >( static_cast< U* >( 0 ) );

    typedef typename shared_ptr<T>::element_type E;

    E * p = static_cast< E* >( r.get() );
    return shared_ptr<T>( r, p );
}

template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
{
    (void) const_cast< T* >( static_cast< U* >( 0 ) );

    typedef typename shared_ptr<T>::element_type E;

    E * p = const_cast< E* >( r.get() );
    return shared_ptr<T>( r, p );
}

template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
{
    (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );

    typedef typename shared_ptr<T>::element_type E;

    E * p = dynamic_cast< E* >( r.get() );
    return p? shared_ptr<T>( r, p ): shared_ptr<T>();
}

template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
{
    (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );

    typedef typename shared_ptr<T>::element_type E;

    E * p = reinterpret_cast< E* >( r.get() );
    return shared_ptr<T>( r, p );
}

 

用法

这里只给出一些特殊用法:

class socket_t {}; 
socket_t* open_socket()
{
    cout<<"open socket"<<endl;
    return new socket_t;
}

void close_socket(socket_t *s) 
{
    cout<<"close_socket"<<endl;
}

void anyfunc(void *)
{
    cout<<"hehe"<<endl;
}

int main()
{
    socket_t *s = open_socket();
    shared_ptr<socket_t> p(s, close_socket);

//  shared_ptr<FILE> fp(fopen("./1.txt","r"), fclose);

    shared_ptr<void> v((void*)0, anyfunc);

    return 0;
}

上面出现了两种特殊用法:

  • 定值删除器,如上close_socket函数
  • 使用shared_ptr,在作用域结束时可调用任何函数 :)

本次简单剖析了shared_ptr的类源码,至于shared_count等限于篇幅放在后续博客。
 
参考:

shared_ptr 源码分析 共享指针 说明 shared_ptr类提供类的行为接口. 有专门的父类提供数据管理接口. 实现 涉及到继承,以及引用计数是否需要多线程安全. 控制块的类型. 源码 shared_ptr template<typename _Tp> class shared_ptr : public __shared_ptr<_Tp> { template<typename... _Args> usi.. 阅读详情

相关推荐

shared_ptr源码分析后续

上次剖析了shared_ptr类的源码,本来肯定也是要说shared_count的,不过由于篇幅,shared_count在这篇博客分析。shared_ptr类自身有两个成员,一个就是T类型指针,另一个就是shared_count对象了。shared_ptr把所有的计数任务都交给了该成员,最终指针的销毁也是由该对象去执行的(底层实际还有sp_counted_base)。这是一种解耦的思想。  源码

FreeeLinux's blog 1262

C++深度探索 - shared_ptr源码分析

简要分析 gcc 4.9.0版本下 shared_ptr源码。

Huuaaaaa的博客 2085

智能指针 shared_ptr 的 C++ 实现原理及源码解析

其中,shared_ptr 是最常用的一种智能指针类型,在多线程环境下具有良好的线程安全性和可共享性。shared_ptr 是 C++ 中最常用的智能指针类型,其内部机制基于引用计数机制,并且支持自定义删除器和多线程环境下的线程安全操作。可以发现,在带参构造函数中,会调用基类 _Base 的构造函数,初始化其指针成员和删除器成员。在这里,指针成员的类型为 _Tp*,而删除器则是通过调用 std::default_delete() 获得的。

pytorchCode的博客 364

shared_ptr源码剖析

shared_ptr的源码: 主要又下列这几个文件组成:main.cpp sp_config.h sp_counted_base.h sp_counted_impl.h shared_count.h shared_ptr.h sp_config.h #ifndef _SP_CONFIG_H #define _SP_CONFIG_H #define DISPLAY//配置:在构造和析构的时候是否打印对应的字符串 #endif shared_ptr.h #ifndef _SHREAD_PTR_H #d

王学门徒 1024

FPGA新手避坑指南:手把手教你搞定RTL8211千兆网PHY的时序配置(附Verilog代码)

本文详细解析了FPGA与RTL8211千兆网PHY芯片的时序配置问题,重点介绍了TXDLY/RXDLY引脚设置、FPGA发送端和接收端的Verilog实现,以及调试与验证的完整流程。通过硬件电路设计和代码示例,帮助开发者解决网络连接不稳定、丢包等常见问题,提升千兆网通信的稳定性。

weixin_28732953的博客 542

SAP MM | 采购的自动寻源:货源清单(ME01)与配额协议(MEQ1)的应用与 MRP 逻辑

SAP MM模块中,当物料有多个供应商时,MRP生成的采购申请常因"固定供应商"字段为空而无法自动发单。系统寻源优先级为:配额协议>货源清单>采购信息记录。解决方案包括:1)货源清单指定唯一固定供应商;2)配额协议按比例精准拆分;3)配额协议长期分配更推荐。手工创建采购申请时配额协议无效。建议优先使用货源清单Fix标识或配额分配功能,避免拆分导致的单据碎片化。

RiverRia的专栏 826

shared_ptr & weak_ptr 源码分析

shared_ptr weak_ptr 源码分析,讲解相互构造的过程,记忆引用计数的管理

c553110519的专栏 322

Hypack 应用于地形测量的高级设置操作要领

Hypack 是业界公认最好的水文导航测量软件,是目前世界上应用广泛的专业测量疏浚软件。它能够接收,处理,存储和输出各种数据。Hypack支持绝大部分GPS,测深仪(国内如海鹰HY1603单波束测沙仪),多波束测深仪,旁扫声纳,涌浪补偿器,水位仪,验潮仪以及声速剖面仪。利用 Hypack 可以进行导航,单波束测量,多波束测量,旁扫测量以及疏浚实时监测等。软件界面友好,使用方便。本文简要阐述Hypack 应用于地形测量的几个重要操作要领。

中游鱼的博客 2794

智能指针源码分析(2)——shared_ptr

本篇文章讲述了boost库智能指针之shared_ptr的基本构造,并编写了自己的shared_ptr模板,实现了几个简单的例子,g++编译通过。

Tryturned 328

华为Atlas 300I推理卡驱动安装避坑指南:不同安装方式的选择与优化

本文详细解析华为Atlas 300I推理卡驱动安装的三种主流方式(.run、.rpm和源码编译),提供关键环境检查步骤、安装流程优化建议及常见问题解决方案,帮助开发者高效完成芯片推理卡部署并规避典型安装陷阱。

q9w8e7r6t5的博客 431

FPGA实践教程: 使用HLS将C程序生成IP核心进行FPGA开发

请根据您使用的FPGA开发板和供应商选择适当的HLS工具,并按照他们的安装指南进行安装。根据您使用的FPGA开发板和供应商选择适当的HLS工具,并按照他们的安装指南进行安装。通过本教程,您了解了如何使用HLS工具将C程序生成IP核心,并将其用于FPGA开发。在HLS项目中,您可以对C程序进行设计和优化,以生成对应的IP核心。在HLS项目中,您可以对C程序进行设计和优化,以生成相应的IP核心。将导出的IP核心导入到FPGA项目中。使用FPGA开发环境的菜单中的"导入"或"添加文件"选项导入IP核心。

CqpFsharp的博客 455

源码分析shared_ptr实现

智能指针是C++中一项很常用的技术,合理的使用智能指针可以更方便的管理内存,降低内存泄漏的风险,这里只介绍C++11后官方的智能指针。 智能指针的种类 unique_ptr shared_ptr weak_ptr 关于智能指针使用以及区别可以自行查找资料,这里主要介绍智能指针的实现原理 shared_ptr的实现 我们平时看文档都知道shared_ptr内部是使用引用计数来记录托管指针被引用的次数,当托管指针的引用计数为0时会释放托管的内存,这里通过gcc源码探究shared_ptr内部究竟是如

qq_29426201的博客 1043

12、硬件工程师笔试面试——MOS管(2025版本)

在设计和测试过程中,可以参考相关的EMC测试标准和指南,如CE认证EMC电磁兼容测试介绍 和电磁兼容性(EMC)测试方法与整改指南 ,以及电磁兼容(EMC)的标准与测试内容 ,来确保MOSFET的EMC性能符合行业标准。在高频应用中,MOSFET的开关速度对电路的整体性能至关重要。是一款高电压同步N沟道MOSFET驱动器,具有自举电源电压至114V的能力,宽VCC电压范围,自适应贯通保护功能,以及高达1.4A的峰值顶端栅极上拉电流,适用于分布式电源架构、汽车电源、高密度电源模块和电信系统等应用。

XU157303764的博客 7092

VS 2010 shared_ptr 源码分析

类结构框架 下面这张图来自于网络,已不知原作者。这张图表明了shared_ptr类结构图 _Ref_count_base是在shared_ptr创建的时候new出来的。_Ref_count_base有3个子类,分别对应shared_ptr构造时的3种形式。在shared_ptr的实现中,会根据调用的shared_ptr构造函数的不同,使用不同类型的_Ref_count_base创建。_Re...

LiQian06336的博客 565

【DaVinci Developer专题】-36-创建一个“既读又写”的Sender Receiver Port(SR PR-Port)

有时会遇到SWC需要对一个Port进行“既可以读,也可以写”的操作。以下图为例,Test_A_SWC中Test_A_Port是P-Port;Test_B_SWC中Test_A_Port是R-Port。Test_C_SWC需要对Test_A_Port同时进行“读”和“写”。 该篇将详细介绍PR-Port的创建方法。 目录 1 创建一个S/R Port Interface 2 将一个PR-Port端口添加至Application Component 3 PR-Port端口初始化 4 Run.

「汽车电子助手」的博客 3013

Python实现稳态传热传质的偏微分方程求解

通过这种方法,我们可以求解更复杂的传热传质问题,并对系统的温度和浓度分布进行分析和优化。稳态传热传质是一个重要的工程问题,涉及到物质在空间中的分布以及热量和质量的传递。每次迭代中,我们使用上一次迭代的温度值来计算下一次迭代的温度值。该图显示了平板内部各点的温度分布,其中中心温度为T1,边界温度为T2。接下来,我们创建一个N x N的温度矩阵,并将边界条件初始化为边界温度T2。假设我们有一个矩形平板,其中心温度为T1,四个边界温度为T2。假设平板的长度为L,宽度为W,中心温度为T1,边界温度为T2。

HackDashX的博客 308

C++ 智能指针(unique_ptr, shared_ptr)的源码分析

在博文https://blog.youkuaiyun.com/qq_27717921/article/details/82940519已经介绍了unique_ptr和shared_ptr的使用,但是这两类的智能指针是如何做到管理指针的呢? shared_ptr 头文件 template &lt;typename T&gt; class SharedPointer { public: SharedPo...

哆啦咪~fo 3756

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

shared_ptr智能指针源码分析

先写应用代码 #include <iostream> #include <memory> int main() { std::shared_ptr<int> sptr(new int(42)); // sptr1 = std::make_shared<int>(32); std::shared_ptr<int> sp2 = sptr; std::weak_ptr<int >wptr; wptr = sptr; std::co

irislin1988的博客 1435

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

C++ 智能指针(shared_ptr/weak_ptr)源码分析

C++11目前已经引入了unique_ptr, shared_ptr, weak_ptr等智能指针以及相关的模板类enable_shared_from_this等。shared_ptr实现了C++中的RAII机制,它不仅仅具有一般指针(build-in/raw)的特性,更重要的是它可以自动管理用户在堆上创建的对象的生命周期,让用户不用为内存回收操心,避免内存泄漏。一般的智能指针都定义为一个模板类,...

gigglesun的专栏 1万+

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

std::shared_ptr 的使用

点击查看

qq_28107929的博客 461

muduo源码分析——TCPConnection 以及 bind导致的shared_ptr计数变化分析

注意问题

weixin_44537992的博客 2083

智能指针篇------STL源码分析:shared_ptr 和 weak_ptr、unique_ptr

探究STL中 shared_ptr 和 weak_ptr 源码,分析其各种机制的实现原理:例如 析构动作在创建时捕获、weak_count 的作用、enable_shared_from_this 的实现机制

weixin_44835655的博客 1518

shared_ptr与weak_ptr

本文主要分析了C++中的shared_ptr和weak_ptr智能指针的工作原理及实现机制。shared_ptr采用引用计数管理对象生命周期,支持自定义删除器,但需注意避免循环引用和多指针管理同一裸指针等问题。weak_ptr作为shared_ptr的观察者,不参与引用计数,主要用于解决循环引用和观察对象状态。文章深入剖析了控制块基类sp_count_base的架构,包括引用计数管理、对象释放逻辑等核心机制,并介绍了自定义删除器sp_count_deleter的实现方式。通过源码分析,揭示了智能指针如何通过

m0_47175840的博客 818
上一篇: scoped_array源码剖析
下一篇: shared_ptr源码分析后续
FreeeLinux
博客等级 码龄11年 421粉丝 356原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值