Encapsulation is one of the important concepts of Object-Oriented Programming (OOP). It means combining data and the functions that operate on that data inside a class and controlling how the data can be accessed from outside the class.
Encapsulation means wrapping data and related functions together inside a class.
class Student {
private:
int marks;
public:
void setMarks(int m) {
marks = m;
}
int getMarks() {
return marks;
}
};
Here, the data member marks and the functions that work
with it are contained inside the Student class.
Encapsulation helps control access to the internal data of an object. It can prevent outside code from directly changing data in unwanted ways.
For example, instead of allowing direct access to a bank account
balance, a class can provide controlled functions such as
deposit() and withdraw().
A class provides a natural way to implement encapsulation.
class Employee {
private:
int salary;
public:
void setSalary(int amount) {
salary = amount;
}
int getSalary() {
return salary;
}
};
The class keeps the data and related operations together.
A private data member cannot normally be accessed directly
from outside the class.
class Student {
private:
int marks;
};
This prevents code outside the class from directly writing:
// student.marks = 90;
when marks is private.
Public member functions can be called from outside the class. They can provide controlled access to private data.
class Student {
private:
int marks;
public:
void setMarks(int m) {
marks = m;
}
};
The function setMarks() is accessible from outside the
class.
A getter is a member function used to read the value of a private data member.
class Student {
private:
int marks;
public:
int getMarks() {
return marks;
}
};
The getter provides controlled read access to marks.
A setter is a member function used to assign or change the value of a private data member.
class Student {
private:
int marks;
public:
void setMarks(int m) {
marks = m;
}
};
A setter can also validate the supplied value before storing it.
class Student {
private:
int marks;
public:
void setMarks(int m) {
marks = m;
}
int getMarks() {
return marks;
}
};
int main() {
Student student;
student.setMarks(85);
std::cout <<
student.getMarks();
return 0;
}
The private variable is accessed through public functions.
One benefit of a setter is that it can validate data before storing it.
class Student {
private:
int marks;
public:
void setMarks(int m) {
if (m >= 0 && m <= 100) {
marks = m;
}
}
int getMarks() {
return marks;
}
};
Only values within the specified range are accepted by this setter.
class BankAccount {
private:
double balance;
public:
void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
double getBalance() {
return balance;
}
};
The balance is kept private, while public functions control how it is changed or read.
Encapsulation can help prevent invalid values from being assigned directly.
class Product {
private:
double price;
public:
void setPrice(double p) {
if (p >= 0) {
price = p;
}
}
double getPrice() {
return price;
}
};
A negative price can be rejected by the setter.
A class can provide a getter without providing a setter. This allows outside code to read a value but not directly change it.
class Student {
private:
int rollNumber;
public:
int getRollNumber() const {
return rollNumber;
}
};
If no public setter exists, outside code cannot use a setter to change the value.
A class can provide a setter without providing a getter. This can be useful in specific designs where outside code should provide a value but should not directly read it back.
class SecurityCode {
private:
int code;
public:
void setCode(int value) {
code = value;
}
};
| Access Specifier | Purpose |
|---|---|
| private | Restricts normal direct access from outside the class. |
| public | Provides an interface that outside code can use. |
| protected | Allows access within the class and derived classes. |
Using these access specifiers helps define which parts of a class are exposed and which parts are hidden.
Data hiding means restricting direct access to internal data. Private members are commonly used to achieve this.
class Employee {
private:
double salary;
public:
void setSalary(double amount) {
salary = amount;
}
double getSalary() const {
return salary;
}
};
The implementation details of salary are hidden from code
that uses the class.
These terms are related but describe different ideas.
Private members are one common mechanism for supporting both concepts.
A constructor can initialize private members when an object is created.
class Student {
private:
std::string name;
int marks;
public:
Student(
std::string n,
int m
)
: name(n),
marks(m) {
}
void display() const {
std::cout <<
name << " "
<< marks;
}
};
A class can provide meaningful operations instead of exposing raw data.
class BankAccount {
private:
double balance;
public:
void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
bool withdraw(double amount) {
if (amount > 0 &&
amount <= balance) {
balance -= amount;
return true;
}
return false;
}
double getBalance() const {
return balance;
}
};
The class controls how the balance can change.
Suppose a class exposes an account balance directly:
account.balance = -5000;
This may allow an invalid state if negative balances are not permitted by the application's rules.
Encapsulation can instead provide a controlled operation:
account.withdraw(500);
The class can validate the operation before changing its internal state.
Getter functions are often declared const because reading
data should not modify the object.
class Student {
private:
int marks;
public:
int getMarks() const {
return marks;
}
};
The const qualifier helps communicate that the function
does not modify the object's state.
Encapsulation and abstraction are related OOP concepts, but they are not exactly the same.
A well-designed class can use both concepts.
#include <iostream>
#include <string>
class Employee {
private:
int id;
std::string name;
double salary;
public:
void setData(
int employeeId,
std::string employeeName,
double employeeSalary
) {
if (employeeSalary >= 0) {
id = employeeId;
name = employeeName;
salary = employeeSalary;
}
}
void display() const {
std::cout << "ID: "
<< id
<< std::endl;
std::cout << "Name: "
<< name
<< std::endl;
std::cout << "Salary: "
<< salary;
}
};
int main() {
Employee employee;
employee.setData(
101,
"Rahul",
35000
);
employee.display();
return 0;
}
#include <iostream>
class BankAccount {
private:
double balance;
public:
BankAccount(double amount)
: balance(amount) {
}
void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
bool withdraw(double amount) {
if (amount > 0 &&
amount <= balance) {
balance -= amount;
return true;
}
return false;
}
double getBalance() const {
return balance;
}
};
int main() {
BankAccount account(1000);
account.deposit(500);
account.withdraw(300);
std::cout <<
"Balance: "
<< account.getBalance();
return 0;
}
class Product {
private:
std::string name;
double price;
int quantity;
public:
void setName(
std::string productName
) {
name = productName;
}
void setPrice(double productPrice) {
if (productPrice >= 0) {
price = productPrice;
}
}
void setQuantity(int productQuantity) {
if (productQuantity >= 0) {
quantity = productQuantity;
}
}
double getPrice() const {
return price;
}
};
Each setter can apply rules before changing the private data.
class Student {
private:
int marks;
public:
void setMarks(int m) {
if (m >= 0 && m <= 100) {
marks = m;
}
}
int getMarks() const {
return marks;
}
bool isPass() const {
return marks >= 40;
}
};
int main() {
Student student;
student.setMarks(75);
std::cout <<
"Marks: "
<< student.getMarks()
<< std::endl;
if (student.isPass()) {
std::cout << "Pass";
} else {
std::cout << "Fail";
}
return 0;
}
The class controls how marks are stored and provides meaningful operations for working with the student result.
const for read-only member functions where appropriate.Encapsulation is used throughout software development.
| Concept | Meaning |
|---|---|
| Encapsulation | Combining data and related functions inside a class while controlling access. |
| private | Used to restrict normal direct access to class members. |
| public | Used to provide an interface to outside code. |
| Getter | Function used to read a private value. |
| Setter | Function used to change a private value. |
| Data Hiding | Restricting direct access to internal implementation details. |
| Validation | Checking values before changing object state. |
| Abstraction | Focusing on essential behavior while hiding unnecessary implementation details. |
class BankAccount {
private:
double balance;
public:
BankAccount(double amount)
: balance(amount) {
}
void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
double getBalance() const {
return balance;
}
};
int main() {
BankAccount account(1000);
account.deposit(500);
std::cout <<
account.getBalance();
return 0;
}
Question: What is the main purpose of encapsulation in C++?