David Abrahams skrev:
on Sun Aug 17 2008, Christian Larsen
wrote: Hi,
This is just make sure I'm not being too careful in this situation. So please confirm whether this is correct.
I have a class with two scoped_ptr members, and I want to pass two pointers to the constructor, which will then transfer the ownership of both to the two member scoped_ptrs. I assume the following is not safe:
(I didn't try compiling; using namespace boost and std.)
struct B {};
class A { public: A(B* b1, B* b2) : b1_(b1), b2_(b2) {} private: scoped_ptr<B> b1_; scoped_ptr<B> b2_; };
// Create an A this way: A a(new B, new B);
Is it correct that this could fail if one of the 'new B's throw, thus leaking before the constructor ever started?
Correct. Please see the guideline at http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/shared_ptr.htm#BestPract...
Ah yes, that clarifies it. :) Somehow it didn't show up in my search results. But it baffles me, that the order isn't even specified to be "unordered evaluation of the arguments to one function at a time", i.e. as in the example f(shared_ptr<int>(new int(2)), g()); it surprises me that "new int(2)", and then "g()" can be evaluated _before_ the shared_ptr constructor.
If that is so, is this then the correct way to achieve the same in a safe manner?
struct B {};
class A { public: A(auto_ptr<B>& b1, auto_ptr<B>& b2) : b1_(b1.release()), b2_(b2.release()) {} private: scoped_ptr<B> b1_; scoped_ptr<B> b2_; };
// Create an A this way: A a(auto_ptr<B>(new B), auto_ptr<B>(new B));
No, that has the same problem (your auto_ptr's aren't named). the 2nd new could throw before any auto_ptrs are constructed, because the order of evaluation is unspecified.
Ok, so the correct way to do it in the last example is this? auto_ptr<B> b1(new B); auto_ptr<B> b2(new B); A a(b1, b2); A little more verbose than I had hoped, but ok as long as it is doing what it's supposed to.
HTH,
Yes it did, thank you. Best regards, Christian