weak_ptr,enable_shared_from_this 的使用举例

下面的知识只是为了解决这个问题:

class Hello
{
public:
    void run(int c)
    {  do_sth(c); }
};

Hello* h = new Hello;
Task* t = Bind(&Hello::run,h);  将类指针及类成员函数封装到一个Task类中
thread->PostTask(t);  将Task投递到线程

问题在:投递线程之后,如果h被delete了,此时线程去执行t的时候就会出错,因为h被删除了。
我的期望:在执行t的时候,先检查h是否还存在,不存在则丢弃该Task。

c++中有一个weak_ptr,弱指针。我知道这个可以解决这个问题,但是如何解决?

 

1. weak_ptr对象的创建和值

    (1).直接创建weak_ptr 对象是可以的,但是它的值是 empty

         weak_ptr<int> tem1; //可以创建weak_ptr的对象,但是它的值是empty

    (2).只能用 make_shared函数 或者 shared_ptr 指针初始化 weak_ptr 对象,只有这样weak_ptr 才会有值

         weak_ptr<int> tem1 = make_shared<int>();

         shared_ptr<int> sharedPtr(new int);

         weak_ptr<int> tem3(sharedPtr);

    (3).下面的做法是错误的,编译通不过

         weak_ptr<int> tem(new int);

    (4).把weak_ptr提升为 shared_ptr

         如果weak_ptr是empty,那么下面的代码会抛出异常 :bad_weak_ptr

        weak_ptr<int> tem1;

        shared_ptr<int> sharedPtr(tem1); // 在执行的时候会抛出异常

 

2.enable_shared_from_this的说明

    (1)enable_shared_from_this类的主要内容

         template<class _Ty> class enable_shared_from_this
         {

         public:
            shared_ptr<_Ty> shared_from_this()
            { // return shared_ptr
                return (shared_ptr<_Ty>(_Wptr));
            }
        private:
  
        mutable weak_ptr<_Ty> _Wptr;  
        }

 

    (2).enable_shared_from_this这个类的主要作用是作为一个类的基类,并且派生类唯一能用上的函数就是    shared_from_this()。

          在上面列出的源码里面没有说明 _Wptr 是怎样被赋值的。下面就给出 _Wptr 被赋值的过程:(注意,在vs源码里面没有看到整个过程,因为vs封装了)  

        class S:public    able_shared_from_this<S>{};
       
        Rule: when a class inherits from enable_shared_from_this, it almost always means it should work with shared_ptr together.
       
        What happened behind the scene for shared_ptr<S> p(new S) ?
        (1) enable_shared_from_this construct is called
        (2) S constructor is called
        (3) shared_ptr constructor is called (the magic happens here)
              |
              | ->   __enable_shared_from_this_helper is called in shared_ptr constructor
                              |
                              |-> enable_shared_from_this::_M_weak_assign is called
                                       |
                                       |-> weak_ptr<_Tp>::._M_assign(__p, __n);
                                             (called on mutable enable_shared_from_this::_M_weak_this instance in
                                               struct S object. This calls sets (inits) the weak_ptr in struct S object)
                                                 |
                                                 |-> Set weak_ptr<_Tp>::_M_ptr and
                                                              weak_ptr<_Tp>:: _M_refcount (__weak_count<_Lp>)

 

       从上面的赋值过程可以看出,如果只是定义一个 S 的对象,那么就不会涉及到 shared_ptr ,所以在调用 shared_from_this() 这个函数的时候,因为 _Wptr 是empty,所以会抛出异常。

 

 

3.具备了 weak_ptr 和  enable_shared_from_this 知识后就可以解决上面的问题了:

解决问题的核心是:保存一个weak_ptr对象,这个weak_ptr对象是 shared_ptr的 observer,并且weak_ptr不能提升为 shared_ptr的话 就可以用下面的判断语句。

class Hello:public enable_shared_from_this<Hello>
{
public:
    void run()
    {
        std::cout<<"run" <<std::endl;
    }
};

class Thread
{
public:
    Thread(shared_ptr<Hello> SPtr):_WPtr(SPtr){}
    void task(boost::function<void()>)
    {
        shared_ptr<Hello> SPtr;
        SPtr = _WPtr.lock();
        if (!SPtr) //如果 weak_ptr 不能提升为 shared_ptr 那么说明这个对象已经不存在了。
        {
            std::cout<<"the hello is not exist"<<std::endl;
            return;
        }

        SPtr->run();
    }

private:
    weak_ptr<Hello> _WPtr;
};


void main()
{
    shared_ptr<Hello> sharedHello(new Hello);

    boost::function<void()> f1;

    f1 = boost::bind(&Hello::run, sharedHello);

    Thread myThread(sharedHello);
    myThread.task(f1);
}

     

       

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值