CodeBlanks Logo Icon CodeBlanks

Summary - Encapsulation

Combine private, getter/setter and const to write an Account class.

Summary - Encapsulation

In this section we deepened encapsulation. private members hide data; getters and setters provide controlled access and validation. const methods promise immutability; constant objects can only call these.

mutable members can be modified inside const methods; this is useful for caching. friend functions can access private members from outside; useful for operator overloading. Now we will bring these together in a task.

Practice Define the Sensor class with encapsulation

Define a Sensor class. Under private: add int reading; and mutable int reads;. Under public: add void setReading(int r) { if (r >= 0) reading = r; }, int getReading() const { reads++; return reading; } and int getReads() const { return reads; }. In main create an instance, call setReading(30), call getReading() twice and print getReads() with std::cout.

Starter code

main.cpp
#include <iostream>

// Define the Sensor class here

int main() {
    // Create a Sensor instance and call its methods
    return 0;
}

Sample solution

main.cpp
#include <iostream>

class Sensor {
    int reading;
    mutable int reads;
public:
    void setReading(int r) {
        if (r >= 0) reading = r;
    }
    int getReading() const {
        reads++;
        return reading;
    }
    int getReads() const {
        return reads;
    }
};

int main() {
    Sensor s;
    s.setReading(30);
    s.getReading();
    s.getReading();
    std::cout << s.getReads();
    return 0;
}

Expected output

2

Practice Add a friend function to Sensor

Take the Sensor class above. Under public: add the friend declaration friend void report(const Sensor&);. Outside the class write void report(const Sensor& s) { std::cout << "Reading: " << s.reading; }. In main create Sensor s;, call setReading(25) and call report(s).

Starter code

main.cpp
#include <iostream>

class Sensor {
    int reading;
    mutable int reads;
public:
    void setReading(int r) {
        if (r >= 0) reading = r;
    }
    int getReading() const {
        reads++;
        return reading;
    }
    int getReads() const {
        return reads;
    }
    // Add the friend declaration and report function here
};

int main() {
    // Create a Sensor instance and call report
    return 0;
}

Sample solution

main.cpp
#include <iostream>

class Sensor {
    int reading;
    mutable int reads;
public:
    void setReading(int r) {
        if (r >= 0) reading = r;
    }
    int getReading() const {
        reads++;
        return reading;
    }
    int getReads() const {
        return reads;
    }
    friend void report(const Sensor&);
};

void report(const Sensor& s) {
    std::cout << "Reading: " << s.reading;
}

int main() {
    Sensor s;
    s.setReading(25);
    report(s);
    return 0;
}

Expected output

Reading: 25

End of section

You completed the encapsulation section. You can now hide data with private, provide controlled access with getters and setters, promise immutability with const methods, and manage side state like caches with mutable.

With friend you granted access to external functions when needed. These five OOP topics — classes, constructors, inheritance, library design and encapsulation — form the foundation of C++'s object-oriented side. The next sections cover advanced topics like templates, smart pointers and the STL.

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Why is a getter method made const?

main.cpp
int getX() const { return x; }
  • To make it faster
  • To make it private
  • To state it will not modify the object Correct answer
  • To allow calling from outside

Explanation: const states that the method will not modify the object.

2 Write the mutable keyword

Question
private: ____ int calls;
Answer
private: mutable int calls;

Explanation: mutable allows modification inside a const method.

All lessons in Intermediate