liveBook · Manning

Invariant

As explained in 100 C++ Mistakes and How to Avoid Them

A class invariant is a condition on an object's state that must hold whenever the object is usable, including after construction and public operations.

A class invariant is a condition that must hold whenever an object is usable: after construction and between every sequence of method calls. It defines a consistent, meaningful state for the object’s data and behavior. section 7.2.1 section 7.2

Establish and protect the invariant through the class interface:

  • Constructors initialize every instance variable with a meaningful value or reject construction when valid initialization is impossible. section 7.2.2 section 10.2
  • Mutators validate inputs and leave state unchanged or signal failure when a value falls outside the permitted range. section 7.3
  • Keep representation knowledge inside the class; unnecessary accessors, public state, and protected variables let clients or derived classes bypass its rules. section 8.2 section 8.4
  • Treat copying, assignment, inheritance, and resource ownership as invariant-sensitive operations rather than automatic implementation details. section 8.0 section 7.6

A Person must never have a negative age

A Person class can require an age in its constructor and validate it before initialization. Constructing Person("Joey", -1) then throws instead of creating a partially initialized object. The same rule must govern later state changes; a default constructor that leaves age undefined merely shifts responsibility to callers and makes invalid use easy.

Listing 7.1 A typical textbook structure
struct Person {
    int age;
    std::string name;
};
 
int main() {
    Person p1;
    std::cout << p1.age << " '" << p1.name << "'\n";        #1
    Person p2 = Person();
    std::cout << p2.age << " '" << p2.name << "'\n";        #2
}

The listing contrasts a simple aggregate whose default-created Person may contain undefined or meaningless state with a class that enforces valid construction. section 7.3

How 100 C++ Mistakes and How to Avoid Them covers it

How deep it goes
Explains definition, representation, constructors, mutators, copying, inheritance, and resources through production-style C++ mistakes, stopping short of formal verification.
Examples
Uses Person age validation, Rational arithmetic, Rectangle and Square inheritance, dynamic resources, and shallow versus deep copying.
What it assumes
Assumes basic C++ classes and objects while developing class design, initialization, encapsulation, inheritance, and copying through concrete examples.
What you can do after
Apply C++ constructors, validators, mutators, access control, and copy operations to keep objects valid throughout their lifetimes.
How it connects
Connects encapsulation, constructors, mutators, inheritance, copy constructors, copy assignment, exceptions, and resource management.

Also explained in

Compare how 12 books explain invariant →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 C++ Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.