C++ Encapsulation

Protecting data and controlling access in object-oriented programming

🔒 What is Encapsulation?

Encapsulation is bundling data and methods together while hiding internal details from outside access. It protects object data using access specifiers like private, public, and protected for better security and organization.


// Simple encapsulation example
class BankAccount {
private:
    double balance;  // Hidden data
public:
    void deposit(double amount) {
        balance += amount;
    }
    double getBalance() {
        return balance;
    }
};
                                    

Key Benefits:

✓ Data Protection

✓ Controlled Access

✓ Code Organization

Access Specifiers

🔒

Private

Only accessible within the class

private:
    int secretData;
🌐

Public

Accessible from anywhere

public:
    void display();
🛡️

Protected

Accessible in class and derived classes

protected:
    int familyData;
⚙️

Getters/Setters

Control data access methods

int getValue() {
    return value;
}

🔹 Complete Encapsulation Example

Encapsulation bundles data and methods within a class, hiding internal state and exposing only controlled interfaces. A Student class might keep attributes like name, age, and GPA private, providing public getter and setter methods (e.g., getName(), setAge()). This protects data integrity—for instance, preventing negative ages—and allows internal implementation changes without affecting external code. The output "Name: Alice, Age: 20, GPA: 3.8" is produced via public methods, while the actual data remains secure. Encapsulation is a cornerstone of object-oriented design, promoting maintainable and secure codebases.

#include <iostream>
#include <string>
using namespace std;

class Student {
private:
    string name;
    int age;
    double gpa;

public:
    // Constructor
    Student(string n, int a, double g) {
        name = n;
        age = a;
        setGPA(g);  // Use setter for validation
    }
    
    // Getter methods
    string getName() { return name; }
    int getAge() { return age; }
    double getGPA() { return gpa; }
    
    // Setter methods with validation
    void setName(string n) {
        if (!n.empty()) name = n;
    }
    
    void setAge(int a) {
        if (a > 0 && a < 120) age = a;
    }
    
    void setGPA(double g) {
        if (g >= 0.0 && g <= 4.0) gpa = g;
    }
    
    void display() {
        cout << "Name: " << name << ", Age: " << age 
             << ", GPA: " << gpa << endl;
    }
};

int main() {
    Student s1("Alice", 20, 3.8);
    s1.display();
    
    // Can't access private data directly
    // s1.name = "Bob";  // Error!
    
    // Must use public methods
    s1.setName("Bob");
    s1.display();
    
    return 0;
}

Output:

Name: Alice, Age: 20, GPA: 3.8

Name: Bob, Age: 20, GPA: 3.8

🔹 Data Validation Example

Encapsulation enables robust data validation by intercepting assignments through setter methods before updating private fields. A Temperature class can store a value in Kelvin privately, with public methods for Celsius and Fahrenheit conversions. Setters validate inputs (e.g., rejecting temperatures below absolute zero) and adjust the internal Kelvin value accordingly. The example demonstrates setting 25°C, which automatically converts to 298.15K and 77°F via validated methods. This ensures the object always remains in a consistent, physically possible state, preventing invalid data corruption and centralizing validation logic within the class.

class Temperature {
private:
    double celsius;

public:
    void setCelsius(double temp) {
        if (temp >= -273.15) {  // Absolute zero check
            celsius = temp;
        } else {
            cout << "Invalid temperature!" << endl;
            celsius = -273.15;
        }
    }
    
    double getCelsius() { return celsius; }
    
    double getFahrenheit() {
        return (celsius * 9.0/5.0) + 32;
    }
    
    double getKelvin() {
        return celsius + 273.15;
    }
};

int main() {
    Temperature temp;
    temp.setCelsius(25.0);
    
    cout << "Celsius: " << temp.getCelsius() << "°C" << endl;
    cout << "Fahrenheit: " << temp.getFahrenheit() << "°F" << endl;
    cout << "Kelvin: " << temp.getKelvin() << "K" << endl;
    
    return 0;
}

Output:

Celsius: 25°C

Fahrenheit: 77°F

Kelvin: 298.15K

🧠 Test Your Knowledge

Which access specifier hides data from outside the class?