Home/C++/Classes, invariants, and RAII

Classes, invariants, and RAII

Construction, encapsulation and deterministic cleanup

A class is useful when every public operation must preserve a relationship among values. Constructors establish the invariant before an object becomes usable; methods preserve it. A public data struct is appropriate for an unconstrained snapshot, while mutable service state generally belongs behind methods.

cpp
class PositiveLimit {
 Int value_;
public:
 explicit PositiveLimit(Int value):value_(value) {
  if(value<=0) throw std::invalid_argument("limit");
 }
 Int value() const {return value_;}
};

Member initialization follows declaration order, not the order written in the initializer list. Initialize members directly rather than default-constructing and assigning later. explicit prevents an unintended implicit conversion from an integer into a domain object.

RAII ties resource release to an owner's destructor. Stack unwinding destroys fully constructed local objects when an exception exits a scope. A lock_guard releases its mutex on both normal return and exception; a vector destroys its elements and frees its allocation automatically. Destructors should not throw during cleanup, because a second escaping exception during unwinding terminates the process.

cpp
std::mutex mutex;
{
 std::lock_guard lock(mutex); // released at closing brace, including exception exit
}

Model a bounded stock invariant as 0 <= used <= capacity. A failed reservation must not change used. Avoid overflow by checking requested against capacity-used. Releasing more than currently reserved is invalid and leaves state unchanged. The final practice uses a local reservation guard so returning from any scope restores stock. Its owner must outlive the guard; a borrowed reference does not provide lifetime extension. This makes ownership of the reservation explicit without implementing manual try/catch cleanup at every call site.

Put it into practice

Implement the exercise in a full-screen workspace, then run its tests.

Open practice
Next lessonCopy, move, and the rule of zero