Private data, public interface
Encapsulation means: hide the data, expose only methods that keep it valid. In Python, private is a naming convention (_balance). In C++, private: is enforced by the compiler.
class BankAccount { public: void deposit(double amount) { if (amount > 0) balance_ += amount; } bool withdraw(double amount) { if (amount <= 0 || amount > balance_) return false; balance_ -= amount; return true; } double balance() const { return balance_; } private: double balance_ = 0.0; // default member initializer };
Outside code cannot write acct.balance_ = -999;, it does not compile. Every change flows through deposit/withdraw, where the validation lives. This is lesson 7-1's invariant made enforceable: "the balance is never negative" holds for the object's whole lifetime, because the only code that can touch balance_ is code that checks first. The trailing underscore on balance_ is a common naming convention for private members.
const methods
The const after balance() promises this method does not modify the object. Mark every read-only method const. It documents intent, and it is required when someone holds a const BankAccount& (remember lesson 4-2's read-only references): only const methods are callable through one.
Code exercise · cpp
Run this. The failed withdrawal is rejected by the class itself, not by the calling code.
Destructors close the loop on RAII
A destructor (~ClassName()) runs automatically when the object dies: scope exit for stack objects, delete (or the owning unique_ptr dying) for heap objects. You saw it fire in lesson 6-2's Probe. Now you can read what a real RAII wrapper looks like inside:
class IntArray { public: IntArray(int n) : data_(new int[n]), size_(n) {} // acquire in constructor ~IntArray() { delete[] data_; } // release in destructor int& at(int i) { return data_[i]; } int size() const { return size_; } private: int* data_; int size_; };
Callers of IntArray never write new or delete. The object cannot leak: its destructor runs on every exit path.
One warning for later: if you copy an IntArray, the compiler-generated copy duplicates the pointer, not the array, and both destructors will delete the same memory. Managing that correctly (the "rule of three/five") is a deeper topic. The practical takeaway for now: prefer std::vector, which is this class done right by experts.
Quiz
A method is declared `double balance() const`. What does that const buy you?
Code exercise · cpp
Your turn. Build a class Stopwatch with a private int ticks_ starting at 0, a tick() method that adds 1, a reset() method, and a const method count() returning ticks_. Expected output: `3` then `0`.