views:

81

answers:

2

Hi!

Imagine I create an instance of Foo on the heap in a method/function and pass it to the caller. What kind of smartpointer would I use?

smartptr new_foo() {
    smartptr foo = new Foo();
    return foo;
}

void bar() {
    smartptr foo = new_foo();
    foo->do_something();
    // now autodelete foo, don't need it anymore
}

Ok... now: As far as I understand those smartpointers from boost, scoped_ptr should be the one to be used in bar(). But I can't create it in foo(), as it's not copyable. So I have to create a shared_ptr in foo() and return it. But do I now have to use a shared_ptr in bar(), or can I just "cast" it to an shared_ptr in bar()?

Edit

Thanks for your answers so far! So now I got two solutions:

  • Use only boost::shared_ptr
  • Use std::auto_ptr in the generator foo() and boost::shared_ptr in bar()

Sincerely, I prefer a boost-only solution and won't mix it with STL except there is really a good reason for doing so. So, next question: has the mixed solution any advantage over the boost only solution?

+2  A: 

boost docs suggest they don't mix

If you are transfering ownership then another option at the moment would be auto_ptr e.g.

smartptr new_foo() { 
    std::auto_ptr<Foo> foo = new Foo(); 
    return foo; 
} 

void bar() { 
    std::auto_ptr<Foo> foo = new_foo(); 
    foo->do_something(); 
    // now autodelete foo, don't need it anymore 
} 

however this will then restrict how you can use new_foo() i.e. you can't use it to fill a container (without managing the resource some other way). :(

With C++0x and rvalue references this will be a job for unique_ptr, which will replace auto_ptr and just do what you want

jk
Returning `auto_ptr` doesn't restrict what you can do; you can use it to initialise a `shared_ptr`, or call `release` and do whatever you want with the raw pointer (as long as you remember to delete it eventually).
Mike Seymour
well ok but it resricts what you can do without managing the resource yourself, which is kind of the point of using it in the first place. or at least you need to be careful i.e. no containers of auto_ptr
jk
perhaps the best way to say it is just that auto_ptr has some dangers you need to be aware of, unique_ptr will fix these
jk
So `auto_ptr` has an advantage over boost's smartpointers in this case?
craesh
not so much an advantage as a narrower use case, which happens to match what you want to do, i.e. ownership transfer rather than sharing
jk
Ok, good to know :) Is there some kind of use case documentation for all those smartpointer types out there in the web? I found http://magazin.c-plusplus.de/artikel/Schlaue%20Zeiger%20-%20Boost%20Smart%20Pointer (german), but it covers only the simplest use cases.
craesh
@craesh: the advantages are that you don't have the overhead of reference counting, and you can take ownership away from the `auto_ptr` if you want to manage the object some other way. You can't take ownership away from a `shared_ptr`.
Mike Seymour
+1  A: 

Use boost::shared_ptr

Steve Townsend
I'm not sure I understand what you mean exactly. Can you explain that a little bit?
craesh
In the first example, you are returning the wrapped object so you need to 'share' ownership of the target object between called and caller. Instantiating and returning the object wrapped in a boost::shared_ptr will do exactly that, transferring ownership cleanly from called to caller. In the second example, no ownership transfer is required since the target object is locally scoped, so simpler scoped_ptr is appropriate - making your code exception-safe without unnecessary function in the smartptr wrapper.
Steve Townsend
There is only one example?
Dennis Zickefoose
@Dennis Z - you are right, I misread the code as two decoupled functions. boost::shared_ptr is the only one that makes sense to me here. Thanks for the correction., edited my original answer.
Steve Townsend