Encapsulation in object-oriented programming is a core principle. It helps keep data safe and programs modular. Imagine a School Management App: students can view their class (through a getter), but only the administration system can update it (using a setter). This story highlights how encapsulation mirrors real-world roles. Encapsulation ensures data safety and modular design.
Imagine using a car or a smartphone: you interact with simple controls on the surface, while the complicated wiring and mechanisms are hidden inside. This is exactly what encapsulation provides in software engineering.
“Encapsulation is the practice of hiding the internal details and exposing only what is necessary through a well-defined interface.”
This principle simplifies usage by concealing complexity, allows internal changes without breaking external code, and protects data integrity.
Access Specifiers
Contents
- Access Specifiers
- Public
- Private
- Protected
- Demonstrating Access Specifiers with a Student Class
- Complete Program Demonstrating Access Specifiers
- Output (conceptual)
- Getters and Setters for Private Members
- Example with Student Class
- Explanation
- Protected Members with Derived Class
- Example with Student and GraduateStudent
- Explanation
- Share this:
Access specifiers in C++ determine the visibility and accessibility of members inside and outside of a class. They help enforce encapsulation by controlling how data and functions can be used.
Public
Public members are the part of a class interface that can be freely accessed from outside. They usually represent operations the object exposes.

Syntax:
class Example {
public:
int x; // accessible everywhere
};
Accessible from outside the class.
Private
Private members hold a class’s internal details and are not visible outside the class. Use private
to enforce invariants and prevent arbitrary external mutation; only member functions (and declared friends) can access them.
Syntax:
class Example {
private:
int y; // accessible only within the class
};
Restricted to the class itself.
Protected
Protected members are intended for collaboration with derived classes. They enable extension in subclasses while staying hidden from non-member, non-friend code—use sparingly to avoid tight coupling to internals.
Syntax:
class Example {
protected:
int z; // accessible in class and derived classes
};
Accessible within the class and derived classes.
Access Specifier | Same Class | Derived Class | Outside World |
---|---|---|---|
public | ✅ | ✅ | ✅ |
protected | ✅ | ✅ | ❌ |
private | ✅ | ❌ | ❌ |
Demonstrating Access Specifiers with a Student Class
To better understand the behavior of public
, private
, and protected
, let’s create a Student
class. This class will have data members such as name
, className
, and address
, and we will experiment with placing them under different access specifiers.
class Student {
public:
string name; // Public: accessible directly from outside
private:
string className; // Private: hidden from outside, only accessible inside class
protected:
string address; // Protected: accessible in this class and in derived classes
};
By changing the access specifier, you can observe which members are accessible from outside, which are hidden, and which are reserved for inheritance.
Complete Program Demonstrating Access Specifiers
#include <iostream>
using namespace std;
class Student {
public:
string name; // public
private:
string className; // private
protected:
string address; // protected
public:
void showInfo() {
cout << "Name: " << name << endl;
cout << "Class: " << className << endl;
cout << "Address: " << address << endl;
}
};
int main() {
Student s;
s.name = "Ali"; // allowed (public)
// s.className = "BSSE"; // error (private)
// s.address = "City"; // error (protected)
s.showInfo();
return 0;
}
Output (conceptual)
Name: Ali
Class:
Address:
This simple program demonstrates how public members are accessible, while private and protected members are restricted.
Getters and Setters for Private Members
When class data members are marked as private
, they cannot be accessed directly from outside the class. To read or write their values safely, we use special functions called getter and setter.
- Setter functions allow assigning a value to a private member in a controlled way.
- Getter functions allow retrieving the value of a private member without exposing it directly.
Example with Student Class
#include <iostream>
using namespace std;
class Student {
private:
string className; // private member
public:
void setClassName(string c) {
className = c; // setter assigns value
}
string getClassName() {
return className; // getter returns value
}
};
int main() {
Student s;
s.setClassName("BSSE"); // using setter to set value
cout << s.getClassName(); // using getter to get value
return 0;
}
Explanation
- The private member
className
cannot be accessed directly. - The setter
setClassName
provides a safe way to assign a value. - The getter
getClassName
provides a way to read the value.
This ensures data hiding and controlled access to private fields.
Protected Members with Derived Class
When a data member is declared as protected
, it is not accessible from outside the class, but it can be accessed inside the class itself and inside its derived classes. This makes protected
useful when you want child classes to reuse or extend internal details without exposing them to everyone.
Example with Student and GraduateStudent
#include <iostream>
using namespace std;
class Student {
protected:
string address; // protected member
public:
void setAddress(string a) {
address = a;
}
};
class GraduateStudent : public Student {
public:
void showAddress() {
cout << "Address: " << address << endl;
}
};
int main() {
GraduateStudent gs;
gs.setAddress("University Campus"); // setter from base class
gs.showAddress(); // derived class accesses protected member
return 0;
}
Explanation
address
is protected, so it is not accessible directly frommain()
.- The derived class
GraduateStudent
can accessaddress
and use it inside its own functionshowAddress
. - This shows how
protected
allows inheritance-based access while keeping the member hidden from external code.