Practical Examples of Encapsulation in C++
Encapsulation is one of the fundamental principles of object-oriented programming (OOP). It involves bundling data (variables) and methods (functions) that operate on the data into a single unit, typically a class. Encapsulation also restricts direct access to some of the object's components, promoting data hiding and ensuring controlled access through public methods.
Why Use Encapsulation?
Encapsulation offers several benefits, including:
- Protecting data from unauthorized access or modification.
- Improving code maintainability by isolating changes.
- Enabling modular design by encapsulating functionality within classes.
- Allowing validation or preprocessing of data before modification.
Practical Example 1: Bank Account Management
This example demonstrates encapsulation by controlling access to a bank account's balance:
#include <iostream> class BankAccount { private: double balance; public: BankAccount() : balance(0) {} void deposit(double amount) { if (amount > 0) { balance += amount; } else { std::cout << "Invalid deposit amount.\n"; } } void withdraw(double amount) { if (amount > 0 && amount <= balance) { balance -= amount; } else { std::cout << "Invalid withdrawal amount.\n"; } } double getBalance() const { return balance; } }; int main() { BankAccount account; account.deposit(1000); std::cout << "Balance: " << account.getBalance() << std::endl; account.withdraw(500); std::cout << "Balance: " << account.getBalance() << std::endl; account.withdraw(600); // Invalid withdrawal return 0; }
Output:
Balance: 1000 Balance: 500 Invalid withdrawal amount.
The private balance
member is protected from direct access, ensuring controlled modifications through the deposit
and withdraw
methods.
Practical Example 2: Student Management System
In a student management system, encapsulation can ensure that data like grades and names are accessed and modified in a controlled way:
#include <iostream> class Student { private: std::string name; int grade; public: void setName(const std::string& studentName) { name = studentName; } void setGrade(int studentGrade) { if (studentGrade >= 0 && studentGrade <= 100) { grade = studentGrade; } else { std::cout << "Invalid grade.\n"; } } std::string getName() const { return name; } int getGrade() const { return grade; } }; int main() { Student student; student.setName("Alice"); student.setGrade(85); std::cout << "Name: " << student.getName() << ", Grade: " << student.getGrade() << std::endl; student.setGrade(150); // Invalid grade return 0; }
Output:
Name: Alice, Grade: 85 Invalid grade.
Encapsulation ensures that the grade is validated before being set, preventing incorrect or out-of-range values.
Practical Example 3: Car Class
This example demonstrates encapsulation for a car object, managing its speed:
#include <iostream> class Car { private: int speed; public: Car() : speed(0) {} void accelerate(int amount) { if (amount > 0) { speed += amount; std::cout << "Accelerated to " << speed << " km/h\n"; } } void brake(int amount) { if (amount > 0 && speed - amount >= 0) { speed -= amount; std::cout << "Slowed down to " << speed << " km/h\n"; } else { std::cout << "Invalid brake operation.\n"; } } int getSpeed() const { return speed; } }; int main() { Car myCar; myCar.accelerate(50); myCar.brake(20); myCar.brake(40); // Invalid operation return 0; }
Output:
Accelerated to 50 km/h Slowed down to 30 km/h Invalid brake operation.
Encapsulation ensures that the speed
is modified only through methods that enforce logical rules.
Conclusion
Encapsulation is a critical principle in C++ that helps build robust and maintainable programs. By grouping data and methods together and restricting direct access to private members, developers can ensure data integrity, enforce validation, and maintain modularity.