繁体   English   中英

提高shared_ptr:运算符=和重置之间的区别?

[英]boost shared_ptr: difference between operator= and reset?

下面的两段代码之间有什么区别吗? 他们中的任何一个比另一个更可取吗?

运算符=

boost::shared_ptr<Blah> foo; // foo.ptr should be NULL
foo = boost::shared_ptr<Blah>(new Blah()); // Involves creation and copy of a shared_ptr?

重启

boost::shared_ptr<Blah> foo; // foo.ptr should be NULL
foo.reset(new Blah()); // foo.ptr should point now to a new Blah object

注意:我需要定义shared_ptr,然后将其设置在另一行中,因为我在一段代码中使用它,例如:

boost::shared_ptr<Blah> foo;
try
{
  foo.reset...
}
foo...

operator=shared_ptr分配给shared_ptr ,而reset使shared_ptr拥有指针的所有权。 因此,您发布的示例之间基本上没有区别。 就是说,您不应该选择其中任何一个,而只需使用make_shared

foo = boost::make_shared<Blah>();

另外,如果可能的话,可以通过将try-catch块包装在一个单独的函数中来避免在不进行初始化的情况下声明shared_ptr ,该函数只需将shared_ptr返回到新创建的对象:

boost::shared_ptr<Blah> createBlah() {
    try {
        // do stuff
        return newBlah;
    }
    catch ...
}

operator=将另一个shared_ptr作为参数,从而创建另一个副本(并增加引用计数),而reset()获取一个指针和一个可选的删除器,从而实际上在当前副本的顶部创建一个新的shared_ptr。

reset等效于(并且可能实现为)

void reset(T p, D d)
{
   shared_ptr shared(p,d);
   swap( shared );
}

operator=可能实现为:

shared_ptr& operator=( shared_ptr const& other )
{
   shared_ptr shared(other);
   swap(other);
   return *this;
}

这两个函数的相似之处在于,它们释放对它们已经包含的内容的控制(如果有的话),而是管理一个不同的指针。

foo.reset(p)定义为与shared_ptr(p).swap(foo)等效。

分配在逻辑上等效于复制和交换,并且可能以这种方式实现。 所以foo = shared_ptr(p); 等效于foo.swap(shared_ptr(p)) 如果编译器的日子很不好,可能在其中有一个额外的副本。

因此,在您提供的示例中,我认为它们之间没有太多选择。 可能还有其他情况很重要。 但是reset与模板构造函数所做的相同,是基于模板的静态类型p的基于模板的捕获,因此就获得正确的删除器而言,您已经了解了。

分配的主要用途是当您要复制先前存在的shared_ptr ,以共享同一对象的所有权时。 当然,从临时分配时也可以正常工作,如果您查看不同的reset重载,它们将反映不同的构造函数。 因此,我怀疑您可以通过任何一种方式实现相同的目标。

赋值运算符从现有对象创建一个新的共享对象,从而增加引用计数

CSharedObj& CSharedObj::operator=(CSharedObj& r) noexcept
{ 
     if(*this != r){
        //detach from the previous ownership
        if(0 == dec()) delete m_pControlObj;
        //attach to the new control object and increment the reference count
        r.inc();
        m_pControlObj = r.m_pControlObj;
    }
    return *this;
}

而reset调用不会创建新的共享库,而是创建新的所有权-附加到新的基础pointee(通过控制对象)

void CSharedObj::reset(Ptr pointee) noexcept
{
   //check if this is a last reference-detach from the previous ownership
   if(0==dec()) delete m_pControlObj;
   // create the ownership over the new pointee (refCnt = 1)
   m_pControlObj = new (std::nothrow) CControlObj(pointee);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM