Not only is this shorter than the original exception-unsafe example, it meets the strong exception safety guarantee. (Sadly it doesn’t compile with Visual C++ - but a strategically placed “using std::swap” avoids the bugs in its name lookup.)
Look at why it works:
Everything that may throw is done before changes are made.
Each resource has an owner whose destructor releases it.
The destructors for the temporaries are called if the function is left via an exception (or by a normal return).
Oh, by the way I’ve not forgotten about self assignment - think about it.
[Articles on assignment by Francis Glassborow Overload 19 and by Kevlin Henney in Overload 20 & 21 and an article by Kevlin C++ Report in August 1997.]