Skip to content

Chapter 17 of 31

Encapsulation and Data Hiding

Protect invariants with small interfaces, access control, and dependency boundaries.

30 minutes 10 quick checksBy Subha Prasad
Lesson 17 of 31Course navigation

Lesson content

Read, practise, then check your understanding

Encapsulation groups data with operations that preserve its rules. private members are accessible to the class and friends, protected also exposes them to derived classes, and public forms the client interface. Data hiding is a mechanism; a stable abstraction is the goal.

#include <stdexcept>

class Percentage {
    double value_{};
public:
    explicit Percentage(double value) { set(value); }

    double value() const noexcept { return value_; }

    void set(double value) {
        if (value < 0.0 || value > 100.0) {
            throw std::out_of_range{"percentage"};
        }
        value_ = value;
    }
};

Making value_ public would allow invalid state. A setter is valuable only when mutation is meaningful and validated; do not generate getters and setters mechanically for every field.

Boundaries and coupling

Keep implementation details out of public headers when build isolation or binary stability matters. A private implementation (pImpl) can hide heavy dependencies behind an owning pointer. Prefer composition over inheritance when one object simply has another capability.

Const member functions expose read-only behavior. Return values or views whose lifetime is clear; returning mutable references to internals can bypass invariants. Classes should have focused responsibilities, minimal public APIs, and dependencies passed explicitly. Strong encapsulation makes internal representation replaceable without rewriting clients and localizes the proof that every valid object stays valid.

Knowledge check

Answer every question correctly to complete this chapter.

What does encapsulation combine?
Which access level best hides implementation data?
What is a class invariant?
Why avoid trivial setters for every field?
What is the default member access of struct?
What is data hiding?
What should a constructor establish?
Why return const observations where appropriate?
What is a leaky abstraction?
Which operation is clearer than setBalance(-10)?

0 of 10 checks passed

Your progress is saved on this device.