• boost enable_shared_from_this


    关于shared_ptr和weak_ptr看以前的:http://www.cnblogs.com/youxin/p/4275289.html

     The header <boost/enable_shared_from_this.hpp> defines the class template enable_shared_from_this. It is used as a base class that allows a shared_ptr to the current object to be obtained from within a member function.

    class Y: public enable_shared_from_this<Y>
    {
    public:
    
        shared_ptr<Y> f()
        {
            return shared_from_this();
        }
    }
    
    int main()
    {
        shared_ptr<Y> p(new Y);
    // 调用f获得shared_ptr
    
        shared_ptr<Y> q = p->f();
        assert(p == q);
        assert(!(p < q || q < p)); // p and q must share ownership
    
    }

     一篇文章:

    使用情景:当类对象被 shared_ptr 管理时,需要在类自己定义的函数里把当前类对象作为参数传给其他函数时,这时需要传递一个 shared_ptr ,否则就不能保持 shared_ptr 管理这个类对象的语义(因为有一个 raw pointer 指向这个类对象,而 shared_ptr 对类对象的这个引用没有计数,很有可能 shared_ptr 已经把类对象资源释放了,而那个调用函数还在使用类对象——显然,这肯定会产生错误)。
     
    很好奇这个模板类的实现。
     
    先看看怎么使用:
     
    对一个类 A ,当我们希望使用 shared_ptr 来管理其类对象时,而且需要在自己定义的函数里把类对象 shared_ptr (为什么不用普通指针,当我们使用智能指针管理资源时,必须统一使用智能指针,而不能在某些地方使用智能指针某些地方使用 raw pointer ,否则不能保持智能指针的语义,从而产生各种错误)传给其他函数时,可以让类 A 从 enable_shared_from_this 继承:
     
    class A : public boost::enable_shared_from_this<A> {
    };
     
    然后在类 A 中需要传递类对象本身 shared_ptr 的地方使用 shared_from_this 函数来获得指向自身的 shared_ptr 。
     
    一个非常有代表性的例子:
     
     
    另《Beyond the C++ Standard Library》 shared_ptr 节也有很简单明了的例子。
     
    实现原理:
     
    首先要考虑的是:在类对象本身当中不能存储类对象本身的 shared_ptr ,否则类对象 shared_ptr 永远也不会为0了,从而这些资源永远不会释放,除非程序结束。
     
    其次:类对象肯定是外部函数通过某种机制分配的,而且一经分配立即交给 shared_ptr 管理(再次强调一遍:给 shared_ptr 管理的资源必须在分配时交给 shared_ptr ),而且以后凡是需要共享使用类对象的地方必须使用这个 shared_ptr 当作右值来构造产生或者拷贝产生另一个 shared_ptr 从而达到共享使用的目的。
     
    有了以上两点的限制,要实现我们的目标(即在类对象内部使用类对象的 shared_ptr )有以下两种方案:
     
    1、类对象的外部 shared_ptr 作为函数参数传给类的需要引用类对象自身的函数——显然,这种方法很丑陋,而且并不是所有的情况都可行(如在外部 shared_ptr 不可见的作用域中就不行);
     
    2、类对象自身存储某种信息,在需要自身 shared_ptr 时来产生一个临时的 shared_ptr 。
     
    显然,第2种方法更优雅(对于用户来说),关键是信息怎么存储?
     
    对了, weak_ptr !
     
    实际上, boost 中就是这样实现的。
     
    但现在的问题是:何时初始化这个 weak_ptr ?因为类对象生成时还没有生成相应的用来管理这个对象的 shared_ptr 。
     
    boost 1.39.0 中是这样实现的:
     
    首先生成类 A :会依次调用 enable_shared_from_this 的构造函数(定义为 protected ),以及类 A 的构造函数。在调用 enable_shared_from_this 的构造函数时,会初始化定义在 enable_shared_from_this 中的 weak_ptr (调用其默认构造函数),这时这个 weak_ptr 是无效的(或者说不指向任何对象)。
     
    接着:外部程序会把指向类 A 对象的指针作为初始化参数来初始化一个 shared_ptr 。
     
    现在来看看 shared_ptr 是如何初始化的, shared_ptr 定义了如下构造函数:
     
    template<class Y>
        explicit shared_ptr( Y * p ): px( p ), pn( p ) 
        {
            boost::detail::sp_enable_shared_from_this( this, p, p );
        }
     
    里面调用了  boost::detail::sp_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 )
    {
        if( pe != 0 )
        {
            pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
        }
    }
     
    里面又调用了 enable_shared_from_this 的 _internal_accept_owner :
     
    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 );
            }
        }
     
    而在这里对 enable_shared_from_this 的成员 weak_ptr 进行拷贝赋值,使得整个 weak_ptr 作为类对象  shared_ptr 的一个观察者。
     
    这时,当类对象本身需要自身的 shared_ptr 时,就可以从这个 weak_ptr 来生成一个了。
     
    原来如此。
    转自:http://blog.csdn.net/zhongguoren666/article/details/8617436
     
    make_shared

    shared_ptr很好地消除了显式的delete调用,如果读者掌握了它的用法,可以肯定delete将会在你的编程字典中彻底消失 。

    但这还不够,因为shared_ptr的构造还需要new调用,这导致了代码中的某种不对称性。虽然shared_ptr很好地包装了new表达式,但过多的显式new操作符也是个问题,它应该使用工厂模式来解决。

    因此,shared_ptr在头文件<boost/make_shared.hpp> 中提供了一个自由工厂函数(位于boost名字空间)make_shared<T>(),来消除显式的new调用,它的名字模仿了标准库的 make_pair(),声明如下:

    1. template<class T, class... Args> 
    2.     shared_ptr<T> make_shared( Args && ... args ); 

    make_shared()函数可以接受最多10个参数,然后把它们传递给类型T的构造函数,创建一个shared_ptr<T>的对 象并返回。make_shared()函数要比直接创建shared_ptr对象的方式快且高效,因为它内部仅分配一次内存,消除了shared_ptr 构造时的开销。

    下面的代码示范了make_shared()函数的用法:

    1. #include <boost/make_shared.hpp> 
    2. int main()  
    3. {  
    4.     shared_ptr<string> sp =  
    5.                 make_shared<string>("make_shared");
      //创建string的共享指针  
    6.     shared_ptr<vector<int> > spv =  
    7.                 make_shared<vector<int> >(10, 2);      
      //创建vector的共享指针  
    8.     assert(spv->size() == 10);  

    make_shared()不能接受任意多数量的参数构造对象,一般情况下这不会成为问题。实际上,很少有如此多的参数的函数接口,即使有,那也会是一个设计的不够好的接口,应该被重构。

    除了make_shared(),smart_ptr库还提供一个allocate_shared(),它比make_ shared()多接受一个定制的内存分配器类型参数,其他方面都相同。

  • 相关阅读:
    移动端轮播图
    移动端的注册页面
    点击显示或者消失的效果(手风琴效果)
    canvas的一些简单绘制方法
    用canvas来手动绘画
    canvas标签的运用
    Html5新标签解释及用法
    最近的心得
    浅谈正则表达式
    P3197 [HNOI2008]越狱
  • 原文地址:https://www.cnblogs.com/youxin/p/4728706.html
Copyright © 2020-2023  润新知