const-Correctness & Modern C++ Style

Course 2 · Ch 8 — Course Finale
const-Correctness & Modern C++ Style
The Rule of Five exists to be understood — the Rule of Zero exists to be practiced

Course 2 built templates, containers, smart pointers, move semantics, exceptions, and lambdas. This closing chapter ties them together into the actual practice of writing idiomatic modern C++.

const-Correctness, In Full

cpp1-2 introduced const briefly; cpp1-8 covered const T& parameters. The remaining piece: a const member function promises not to modify the object, enforced by the compiler.

double area() const { return 3.14159 * radius * radius; } // promises not to modify *this

This is a real, propagating discipline — a const object can only call const-qualified member functions on itself.

The Rule of Three

Revisiting cpp1-5's own preview directly: if a class defines any one of a destructor, a copy constructor, or a copy assignment operator, it almost certainly needs all three. It's managing a resource manually, and the compiler's own default-generated versions of the other two would perform a shallow copy — two objects both believing they own the same resource, leading straight to c2-3's own double-free bug class.

The Rule of Five

C++11 extended it: the move constructor and move assignment operator (cpp2-5's own material) join the same rule. Writing any one of the five is a real signal you likely need to think through all five.

The Rule of Zero

The modern, actually-recommended alternative: don't manage raw resources directly at all. Use RAII wrappers — smart pointers (cpp2-4), STL containers (cpp2-2) — for every member, and let the compiler's default-generated destructor, copy, and move operations work correctly automatically, since each member's own RAII type already does the right thing on its own. A genuine, real best practice: the Rule of Five exists to be understood; the Rule of Zero exists to be practiced. Most well-written modern C++ classes need none of the five written by hand.

class Owner { std::unique_ptr<Resource> res; // RAII member — no destructor/copy/move needed by hand at all };

auto and Range-Based for Loops, Revisited

cpp1-2's auto and cpp2-3's range-based for, named together now as part of "modern C++ style" — alongside the Rule of Zero, smart pointers, and RAII, this is what a well-written modern codebase actually looks like, in sharp contrast to older, pre-C++11 "C with Classes" style still using raw new/delete and hand-written Rule-of-Three classes everywhere.

Closing Course 2

Templates → STL containers → iterators/algorithms → smart pointers → move semantics → exceptions → lambdas — now const-correctness and the Rule of Zero tie the whole course together into a genuine practice, not just a list of features. Course 3 goes deeper still: multiple inheritance, templates in more depth, the Rule of Five's full mechanics, concurrency, C++-specific undefined behavior, and a real capstone.

ConceptOld "C with Classes"Modern C++
Resource managementraw new/delete, hand-written Rule of Three/FiveRAII wrappers, Rule of Zero
Containershand-rolled or raw arraysstd::vector/std::map and the rest of the STL
Type declarationsalways spelled out explicitlyauto where it aids readability
Writing a destructor by hand? Stop and ask why
In modern C++, hand-writing a destructor is a real signal worth pausing on — could an existing RAII type (a smart pointer, a container) hold that resource instead? The Rule of Zero as a practical, everyday habit, not just a rule to recite.
Following neither Rule leaves a genuine double-free trap
A class manually managing a raw pointer member, but relying on the compiler's default-generated copy constructor (following neither the Rule of Five nor the Rule of Zero), gets a shallow copy — two objects both pointing at the same heap memory, both believing they own it, leading straight to a double-free exactly like c2-3's own bug catalog.

Coding Challenges

Challenge 1

Write a class with a const member function that computes and returns a value from the object's own data without modifying it. Then attempt to call a non-const member function on a const instance of that class, and report the compile error.

📄 View solution
Challenge 2

Write a class that follows the Rule of Zero by holding a std::unique_ptr as its only member, with no hand-written destructor, copy, or move operations at all. Demonstrate that moving an instance still works correctly.

📄 View solution
Challenge 3

Write a class managing a raw new'd int* member with a hand-written destructor, but deliberately no copy constructor or copy assignment operator. Copy an instance of it, let both copies go out of scope, and explain precisely what goes wrong.

📄 View solution

Chapter 8 Quick Reference — Course 2 Complete

  • const member functions — a compiler-enforced promise not to modify the object
  • Rule of Three — destructor, copy constructor, copy assignment: write one, likely need all three
  • Rule of Five — the Rule of Three plus move constructor and move assignment (C++11)
  • Rule of Zero — the modern practice: hold RAII members only, let the compiler generate everything correctly
  • Modern C++ style: RAII, smart pointers, the STL, auto, range-based for — vs. older raw new/delete "C with Classes"
  • Course 2 complete. Course 3 covers multiple inheritance, deeper templates, the Rule of Five in full, modern concurrency, C++-specific UB, and a real capstone