# Lecture 18: Protect object invariants across their lifetime ## Protect invariants and make object lifetime predictable **Instructor:** [Dr. Debasish Pattanayak](https://drdebmath.github.io)
## A class protects state by combining data, behavior, and access control ~~~cpp class Counter { private: int value = 0; public: void increment() { ++value; } int current() const { return value; } }; ~~~ The invariant is:
value >= 0
. The public interface preserves it because it can only increment.
## Constructors establish valid initial state before use ~~~cpp class Rectangle { double length; double width; public: Rectangle(double l, double w) : length(1.0), width(1.0) { if (l > 0.0) length = l; if (w > 0.0) width = w; } double area() const { return length * width; } }; ~~~ Overloaded constructors may offer several distinct valid initialization paths.
## Copy construction creates; assignment replaces an existing value ~~~cpp Rectangle first(4.0, 3.0); Rectangle copied = first; // copy construction: new object Rectangle assigned(1.0, 1.0); assigned = first; // copy assignment: existing object ~~~ Value members such as numbers and strings usually support the Rule of Zero.
## RAII binds resource release to object lifetime A destructor runs when an object's lifetime ends. RAII stores a resource in an owning object whose destructor releases it. Prefer
std::string
,
std::vector
, and smart pointers over handwritten ownership and deep-copy code.
## Overloaded operators preserve the meaning users expect from values Useful value-type operations include: -
operator+
returning a new value; -
operator==
comparing observable state; -
operator<<
inserting into a stream; - copy assignment safely replacing an existing value. Do not change an operator's expected meaning.
## Value types depend on invariants, ownership, and predictable lifetime - A class should protect a meaningful invariant. - Constructors initialize; assignment replaces an existing value. - Destruction ends lifetime and releases owned resources. - Prefer Rule-of-Zero member types. - Overloads must keep interfaces unsurprising.