简体   繁体   中英

Should private function members be exception safe?

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.

This is my opinion.

If there is a possibility that DoSomeOfIt will be used by more than one function, it'll be better to have the exception handling code reside in that function itself -- you don't want to have the exception handling code duplicated across multiple functions. If that is not a possibility, your posted code is fine.

Having said that, if you move the exception handling code to DoSomething , you don't lose anything. In fact, the function becomes better. If it is used in the future by another function, the exception handling is already taken care of. Looked at from that point of view, it will be better to move the exception handling code to DoSomething .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM