Lesson 2 · 2 of 20
Encapsulation and initializer lists · C++
Protect a C++ class's data with private members and getters, and build its members with an initializer list: a thermostat that stays in range.

Encapsulation means hiding the data and letting only the class itself change it. Everything in a class is private by default, so room_, target_, min_, max_ and changes_ are invisible from main: writing living.target_ = 99; would be a compile error. The trailing underscore is just a habit that makes members easy to spot.
Whatever comes after public: is the class's interface. set() is the only way to change the temperature, so it can guarantee the value always stays between min_ and max_: 35 degrees in the living room becomes 28, and 10 in the office goes up to 18. target() is a getter: it lets you read the value but not change it.
The constructor uses a member initializer list: what follows the colon, : room_(room), target_(target), min_(min), max_(max), builds each member directly with its value instead of creating it empty and assigning it later. It is required for const members such as min_ and max_, which cannot be assigned in the body.
Members are initialized in the order they are declared, not the order of the list, so write the list in that same order (with -Wall the compiler warns you otherwise). int changes_ = 0; is a default member initializer, used by any constructor that does not say otherwise.
The parameters min = 15 and max = 28 have default values: the living room is created with two arguments and gets that range, while the office passes all four to limit itself to 18–24.
Code · main.cpp
#include <iostream>#include <string>class Thermostat { // A class is private by default: only its own methods can touch these. std::string room_; double target_; const double min_, max_; // const members must be set in the list int changes_ = 0; // default member initializerpublic: // Initializer list: members are built directly, in declaration order. Thermostat(std::string room, double target, double min = 15, double max = 28) : room_(room), target_(target), min_(min), max_(max) {} // The only way to change the target, so it always stays in range. void set(double t) { target_ = t < min_ ? min_ : (t > max_ ? max_ : t); ++changes_; } double target() const { return target_; } // read-only access void show() const { std::cout << room_ << ": " << target_ << " C (changes: " << changes_ << ")\n"; }};int main() { Thermostat living("Living room", 21); Thermostat office("Office", 20, 18, 24); living.show(); living.set(35); // too hot: clamped to 28 office.set(10); // too cold: clamped to 18 living.show(); office.show(); std::cout << "Average: " << (living.target() + office.target()) / 2 << " C\n";}Output · c++ -std=c++17 main.cpp -o main && ./main
Living room: 21 C (changes: 0) Living room: 28 C (changes: 1) Office: 18 C (changes: 1) Average: 23 C
Key points
- In a
class, members are private unless they come afterpublic:. - Private data only changes through methods that validate it.
- A
constgetter allows reading without allowing changes. - The initializer list builds the members;
constmembers need it. - Write the list in the order the members are declared.
Exercise
Add a warmer() method that raises the target by half a degree with set(target_ + 0.5) and call it twenty times on the office. Check that it never goes above 24.