Chapter roadmap
Model objects with classes, enforce invariants through constructors, understand addresses and references, and manage resources with RAII. Work through the concepts in order, type every example yourself, and keep a short debugging log that records predictions, errors, fixes, and what each fix taught you.
Learning objectives
- Design a focused class
- Use constructors and encapsulation
- Explain pointers and object lifetime
- Prefer RAII and smart ownership
06.1
Classes and encapsulation
A class combines data with operations that protect it. Private members hide representation details, while public methods form the interface. An invariant is a rule that should remain true after construction and every public operation.
Before running the example, trace each expression and write down the expected state or result. Then run it, compare the actual result, and change one input or rule to confirm that you understand which part controls the behavior.
Exampleclass BankAccount {
private:
std::string owner;
double balance;
public:
BankAccount(std::string name, double opening)
: owner{name}, balance{opening} {}
void deposit(double amount) {
if (amount > 0) balance += amount;
}
double getBalance() const { return balance; }
};ResultBankAccount account{"Mina", 50};
account.deposit(25);
Balance: 75
Check your understandingExplain the example in plain language, identify one boundary or failure case, and revise it so the output changes in a predictable way.
06.2
Constructors and const methods
A constructor creates a valid object and an initializer list constructs members directly. A const member function promises not to modify the observable object and can be called on const instances. Getters should expose only data clients actually need.
Before running the example, trace each expression and write down the expected state or result. Then run it, compare the actual result, and change one input or rule to confirm that you understand which part controls the behavior.
Exampleclass Rectangle {
double width, height;
public:
Rectangle(double w, double h) : width{w}, height{h} {}
double area() const { return width * height; }
};ResultRectangle panel{4.0, 2.5};
panel.area() -> 10
Check your understandingExplain the example in plain language, identify one boundary or failure case, and revise it so the output changes in a predictable way.
06.3
Pointers, references, and lifetime
A pointer stores an address and may be null; a reference is an alias that must refer to an object. Dereferencing accesses the pointed-to value. Never keep a pointer to an object after that object's lifetime ends, and always check nullable pointers before use.
Before running the example, trace each expression and write down the expected state or result. Then run it, compare the actual result, and change one input or rule to confirm that you understand which part controls the behavior.
Exampleint score = 92;
int* scorePointer = &score;
*scorePointer += 3;
std::cout << score;
Result95
Check your understandingExplain the example in plain language, identify one boundary or failure case, and revise it so the output changes in a predictable way.
06.4
RAII and smart pointers
Resource Acquisition Is Initialization ties a resource to an object's lifetime, so cleanup happens automatically in a destructor. Standard containers and strings already follow RAII. When dynamic ownership is necessary, std::unique_ptr expresses one owner and std::shared_ptr expresses shared ownership; raw owning pointers should be avoided.
Before running the example, trace each expression and write down the expected state or result. Then run it, compare the actual result, and change one input or rule to confirm that you understand which part controls the behavior.
Example#include <memory>
auto account = std::make_unique<BankAccount>("Mina", 100.0);
account->deposit(40.0);
std::cout << account->getBalance();Result140
Check your understandingExplain the example in plain language, identify one boundary or failure case, and revise it so the output changes in a predictable way.
Chapter assignments
Complete these in order. Later assignments assume that earlier skills are working. Do not only test the sample values; design tests that challenge boundaries, missing values, incorrect types, empty collections, and other likely failures.
- A6.1
Design a Rectangle class that validates dimensions and provides area, perimeter, scaling, and formatted description methods.
Submit readable source code, a brief design note, and evidence from at least three tests including one boundary or invalid case.
- A6.2
Create a Student class with a private score vector and methods to add scores and calculate statistics.
Submit readable source code, a brief design note, and evidence from at least three tests including one boundary or invalid case.
- A6.3
Trace a program containing values, references, and pointers; draw the objects and addresses after each statement.
Submit readable source code, a brief design note, and evidence from at least three tests including one boundary or invalid case.
- A6.4
Replace a manually allocated object with std::unique_ptr and explain how automatic cleanup changes failure safety.
Submit readable source code, a brief design note, and evidence from at least three tests including one boundary or invalid case.
Chapter project
Library Manager
Library Manager โ Model Book, Member, and Library classes. Support checkout, return, search, overdue status, and reports while preserving valid state. Use vectors for owned collections, const-correct query methods, and smart pointers only if polymorphic ownership is genuinely needed.
Required process
- Write a short specification listing inputs, outputs, rules, and failure cases.
- Break the work into small functions, queries, modules, or classes appropriate to the language.
- Build the smallest working version before adding optional features.
- Test normal, boundary, empty, and invalid cases and record the results.
- Refactor names and duplication, then write a concise user guide.
Key terms
- class
- object
- encapsulation
- invariant
- constructor
- destructor
- pointer
- lifetime
- RAII
- ownership