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

发布于 2024-10-25 01:15:58 字数 602 浏览 4 评论 0原文

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

operator=

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?

reset

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

Are there any differences between the two pieces of code below? Is any of them preferable to the other?

operator=

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?

reset

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

Note: I need to define the shared_ptr and then set it in a different line because I'm using it in a piece of code like:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南风起 2024-11-01 01:15:58

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= assigns a shared_ptr to a shared_ptr, while reset makes a shared_ptr take ownership of a pointer. So, basically there is no difference between the examples you have posted. That said, you should prefer neither of them and just use make_shared:

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

Also, if possible, you can prevent having to declare a shared_ptr without initialization by wrapping the try-catch block in a separate function that simply returns a shared_ptr to the newly created object:

boost::shared_ptr<Blah> createBlah() {
    try {
        // do stuff
        return newBlah;
    }
    catch ...
}
葬花如无物 2024-11-01 01:15:58

operator= 接受另一个 shared_ptr 作为参数,从而创建另一个副本(并增加引用计数),而 reset() 接受一个指针和一个可选的删除器,因此实际上在当前共享指针之上创建了一个新的共享指针。

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

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

operator= takes another shared_ptr as a parameter thus creating another copy (and upping the reference count) while reset() takes a pointer and optionally a deleter, thus in reality creating a new shared_ptr on top of the current one.

reset is equivalent to (and probably implemented as)

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

operator= is likely to be implemented as:

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

The two functions are similar in that they release control of what they are already containing, if any, and manage a different pointer instead.

染火枫林 2024-11-01 01:15:58

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

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

因此,在您给出的示例中,我认为它们之间没有太多选择。可能还有其他重要的情况。但是 Reset 与模板构造函数一样,对 p 的静态类型进行基于模板的捕获,因此就获取正确的删除器而言,您已经可以了。

赋值的主要用途是当您想要复制先前存在的 shared_ptr 时,以共享同一对象的所有权。当然,从临时分配时它也可以正常工作,并且如果您查看不同的重置重载,它们会镜像不同的构造函数。所以我怀疑无论哪种方式你都可以实现同样的目标。

foo.reset(p) is defined to be equivalent to shared_ptr(p).swap(foo).

Assignment is logically equivalent to copy-and-swap, and possibly implemented that way. So foo = shared_ptr(p); is equivalent to foo.swap(shared_ptr(p)). Possibly with an extra copy in there if the compiler is having a very bad day.

So in the examples you give, I don't think there's much to choose between them. There might be other cases where it matters. But reset does the same template-based capture of the static type of p that the template constructor does, so as far as getting the right deleter is concerned, you're covered.

The main use of assignment is when you want to copy a previously-existing shared_ptr, to share ownership of the same object. Of course it works fine when assigning from a temporary too, and if you look at the different reset overloads they mirror the different constructors. So I suspect you can achieve the same things either way.

挽袖吟 2024-11-01 01:15:58

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

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

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

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

Assignment operator create a new shared object from existing one, incrementing the reference count

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

while the reset call doesn't create the new shared object, but rather a new ownership - attaching to the new underlying pointee ( via control object)

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文