boost shared_ptr:operator =和reset之间的区别?

时间:2011-03-18 12:14:32

标签: c++ boost shared-ptr

以下两段代码之间是否有任何差异?他们中的任何一个比另一个好吗?

运算符=

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...

4 个答案:

答案 0 :(得分:15)

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 ...
}

答案 1 :(得分:3)

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;
}

这两个函数类似,它们释放对已经包含的内容的控制权(如果有的话),并改为管理不同的指针。

答案 2 :(得分:2)

foo.reset(p)定义为等同于shared_ptr(p).swap(foo)

分配在逻辑上等同于复制和交换,并且可能以这种方式实现。因此foo = shared_ptr(p);相当于foo.swap(shared_ptr(p))。如果编译器有一个非常糟糕的一天,可能会有一个额外的副本。

所以在你给出的例子中,我认为他们之间没有多少选择。可能还有其他重要的情况。但是重置会对模板构造函数执行的静态类型p进行相同的基于模板的捕获,因此,只要获得正确的删除器,就可以了解它。

分配的主要用途是,您希望复制以前存在的shared_ptr,以共享同一对象的所有权。当然,从临时分配时它也可以正常工作,如果你看一下不同的reset重载,它们会镜像不同的构造函数。所以我怀疑你可以用任何一种方式实现同​​样的目标。

答案 3 :(得分:0)

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

GetCompletedTask()

虽然重置调用不会创建新的共享对象,而是新的所有权 - 附加到新的底层指针(通过控制对象)

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;
}