shared_ptr vs scoped_ptr
Asked Answered
S

5

38

scoped_ptr is not copy able and is being deleted out of the scope. So it is kind of restricted shared_ptr. So seems besides the cases when you really need to restrict the copy operation shared_ptr is better to use. Because sometimes you don’t know you need to create a copy of your object or no. So the question is: besides the cases mentioned above, could we consider that shared_ptr is better (or recommended) to use instead of scoped_ptr. Does scoped_ptr work much faster from shared_ptr, or does it have any advantages?

Thanks!

Slurry answered 20/11, 2009 at 14:7 Comment(0)
U
72

shared_ptr is more heavyweight than scoped_ptr. It needs to allocate and free a reference count object as well as the managed object, and to handle thread-safe reference counting - on one platform I worked on, this was a significant overhead.

My advice (in general) is to use the simplest object that meets your needs. If you need reference-counted sharing, use shared_ptr; if you just need automatic deletion once you've finished with a single reference, use scoped_ptr.

Unrestrained answered 20/11, 2009 at 14:14 Comment(4)
Mike, I couldn't agree more. I always advise people to start with boost::scoped_ptr. If you need transfer of ownership semantics (maintaining single ownership) then "upgrade" to std::auto_ptr. If you need shared ownership only then do you use boost::shared_ptr. Also, the Boost.ptr_container library is a nice alternative to containers of boost::shared_ptr when the elements don't really need to be shared.Linsk
As an aside: if you do need shared pointers, you can get rid of the extra allocations by allocating objects using make_shared or allocate_shared instead of new.Unrestrained
@David: I mostly agreed, but I'd skip auto_ptr entirely. It can't be used safely in standard containers, so it's likely to spring a few nasty surprises if you're not really careful.Noles
Agreed, especially as auto_ptr is deprecated as of c++11, it shouldn't be recommended, instead I'd mention unique_ptr.Pga
A
16

Performance - shared_ptr has more functionality, but also requires an additional allocation (it's also larger, but that rarely matters).

[edit] The second allocation can be avoided by using make_shared, but then weak_ptr will hold the entire entire allocation even after the object is destroyed, which may be a problem for large objects.

Expresison of Intent using scoped_ptr you state more explicitly what you want to do. (In case you wonder - that's a good thing :) ). If you do this correctly, shared_ptr will also indicate "this object is intended to live beyond this scope"

Allimportant answered 20/11, 2009 at 14:20 Comment(1)
+1 for expression of intent. In that vein, scoped_ptr is very clear as is shared_ptr. Likewise, use of std::auto_ptr should signal that you're willing to transfer ownership of the object at some point.Linsk
S
6

Their intended purpose is different, so, in many cases "shared_ptr vs scoped_ptr" is not a question at all. Sure, you can use a shared_ptr when all you need is a scoped_ptr. But what's the point? shared_ptr has likely a slightly bigger overhead with all the reference counting involved.

Surfbird answered 20/11, 2009 at 14:10 Comment(0)
P
3

scoped_ptr works much faster from shared_ptr. It's right. shared_ptr always allocate memory using your allocator or default allocator.

Philips answered 20/11, 2009 at 14:9 Comment(0)
C
1

Scoped_ptr has little in common with shared_ptr, weak_ptr, or unique_ptr because it is only doing very special case of "reference counting". It isn't something you will need very often in well-designed code, but it is a good tool to have available.

Basically, a scoped_ptr isn't a reference-counted thing at all. Rather, it is an object you create on the stack (within the local scope) so that you can do something like this:

  //Some enclosing scope- anything set off by "{}" or even a function:
   {
       scoped_ptr<MyObject> ptr = new MyObject( parameters...);
   } // When we hit this closing brace, "ptr" will delete the "MyObject" inside.

You tend to see this pattern more with mutexes and other synchronization primatives- I can declare an "AutoLock" that will lock the mutex passed into it, then unlock it when it deletes to turn the whole "{}" scope into a critical section.

Also notice that a 'scoped_ptr' only ever makes sense when you can't just do a plain-old stack allocation like "MyObject obj(params..)" for some reason. After all, what it is doing is letting you use a heap-allocated object as if it was one on the stack. That tends to be a lot rarer a use case than the reference-counting of shared_ptr & its cousins.

Clemence answered 1/8, 2014 at 21:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.