When writing exception-safe code, should all private member functions guarantee at least basic exception safety? What would be best/good practice in this situation? Alternatives?
For example, say I have a class Foo
with public
function member DoSomething
, which calls private
function member DoSomeOfIt
. DoSomeOfIt
may fail due to some functions that I cannot influence, and when it does it may leave the Foo
object in a partially modified state which violates Foo
's invariants. So I could wrap DoSomeOfIt
in a try-catch
block and call another private
function member UndoThat
in the catch
block to undo what DoSomeOfIt
did. Individually, DoSomeOfIt
and UndoThat
may not be exception safe, but DoSomething
is. Would that be exception safe code? (In this case with strong guarantee)
class Foo {
public:
// I provide strong exception safety guarantee
void DoSomething() {
try {
DoSomeOfIt();
} catch (const std::exception& e) {
UndoThat();
throw;
}
}
private:
// I provide no exception safety guarantee.
DoSomeOfIt() {
// may throw and violate class invariants.
}
// I provide no exception safety guarantee.
UndoThat() {
// undoes everything most recent call of
// DoSomeOfIt did.
}
};
Of course I could simply include the code of DoSomeOfIt
and UndoThat
in DoSomething
, but that could lead to code bloating, and a long function body, whereas breaking up the functions modularizes the tasks and may make the code more readable(?)
DISCLAIMER: I understand this may be opinion-based. I am not sure if that makes this a bad post, but I'd appreciate any opinions, or experiences where this has lead to issues, or is common practice etc.