提升Shared_Ptr分配

Ton*_*ion 6 c++ boost pointers

为什么我不这样做?

boost::shared_ptr<QueuList> next;

void QueuList::SetNextPtr(QueuList* Next)
{
    boost::mutex mtx;

    boost::mutex::scoped_lock lock(mtx);
    {// scope of lock
        //if (next == NULL)  // is this needed on a shared_ptr??
        next = Next;  // Why can I not assign a raw ptr to a shared_ptr????
    }
Run Code Online (Sandbox Code Playgroud)

}

我应该怎么做呢?

编辑:在正确分配下一个变量时调用此方法,当QueuList对象因某种原因被销毁时仍会导致错误.我得到一个调试断言.对象的析构函数没有做任何特别的事情.它只在我调用此函数时崩溃:

    QueuList li;
    QueuList lis;

    li.SetNextPtr(&lis);
Run Code Online (Sandbox Code Playgroud)

当main超出范围时,我得到一个调试断言......任何想法?

Bjö*_*lex 7

这样做是为了防止意外地将指针分配给shared_ptr其生命周期被独立管理的指针.您必须显式创建一个shared_ptr然后获取对象的所有权.

next = boost::shared_ptr<QueueList>( Next );
Run Code Online (Sandbox Code Playgroud)

编辑您的编辑问题是,在您的情况下,shared_ptr获取堆栈上的对象的所有权.然后会发生两件事:

  1. shared_ptr达到引用计数0 之前,对象的堆栈帧被清除.在这种情况下,shared_ptr将尝试稍后在某处删除不存在的对象,从而导致未定义的行为.
  2. shared_ptr清除堆栈帧之前达到引用计数0.在这种情况下,它将尝试删除堆栈中的对象.我不确切知道在这种情况下会发生什么,但我认为它也是未定义的行为.

  • 或者只使用重置成员函数 - `next.reset(Next);` (5认同)

Mar*_*ram 6

您可以使用Reset()函数而不是wordier next = boost::shared_ptr<QueueList>(Next);

next.Reset(Next);
Run Code Online (Sandbox Code Playgroud)


Dou*_*oug 5

将指针放在一个指向shared_ptrshared_ptr的指针的所有权中,因此shared_ptr它负责删除它.这在概念上是一项重要的操作,因此设计师shared_ptr不希望它只是作为看似正常的作业的一部分而发生.例如,他们想要阻止代码:

some_shared_ptr = some_other_smart_pointer.get();
Run Code Online (Sandbox Code Playgroud)

看起来相当无害,但这意味着两个智能指针都认为他们有责任清理指针,并且可能会双重删除指针或类似的东西.

这就是您的调试断言所发生的事情.调用SetNextPtr(&lis)将所有权传递&lisshared_ptr,并且"所有权"意味着当最后一个副本超出范围时,shared_ptr将调用delete其指针shared_ptr.所以你有效地删除了一个本地(堆栈)变量lis- 它会破坏堆栈并导致崩溃.

  • 好的,是的,所以如果你将`new QueuList()`的结果传递给那个函数,那么你就不会(也绝不)在其他任何地方删除它. (2认同)