codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
⚡

C++ Programming

43 / 87 topics
38OOP Concepts Overview39Classes and Objects40Class Methods41Constructors & Constructor Overloading42Destructors43Access Modifiers / Specifiers44Encapsulation45Abstraction46Friend Functions and Friend Classes47Operator Overloading
Tutorials/C++ Programming/Access Modifiers / Specifiers
⚡C++ Programming

Access Modifiers / Specifiers

Updated 2026-05-12
30 min read

Access Modifiers / Specifiers

In object-oriented programming (OOP), access modifiers or specifiers are keywords used to set the accessibility of class members, such as variables and functions. They control how these members can be accessed from outside the class. Understanding access modifiers is crucial for implementing encapsulation, a fundamental OOP principle that helps in maintaining data integrity and security.

Introduction

Access modifiers help in defining the boundaries of a class by restricting or allowing access to its members. In C++, there are three primary access specifiers: public, private, and protected. Each specifier serves a different purpose and plays a vital role in encapsulating the data within a class.

  • Public: Members declared as public can be accessed from anywhere, both inside and outside the class.
  • Private: Members declared as private can only be accessed within the class itself. They are not accessible to derived classes or external code.
  • Protected: Members declared as protected can be accessed within the class itself and by derived classes. They are not accessible from outside the class hierarchy.

Core Content

Public Access Modifier

The public access specifier is the most permissive one. It allows members to be accessed from any part of the program, both inside and outside the class.

Example:

public_example.cpp
1#include <iostream>
2
3class Person {
4public:
5 std::string name;
6 int age;
7
8 void display() {
9 std::cout << "Name: " << name << ", Age: " << age << std::endl;
10 }
11};
12
13int main() {
14 Person person1;
15 person1.name = "John";
16 person1.age = 30;
17 person1.display();
18
19 return 0;
20}
Output
Name: John, Age: 30

Explanation: In this example, the name and age variables are declared as public. Therefore, they can be accessed directly from the main() function.

Private Access Modifier

The private access specifier restricts member access to within the class itself. Members declared as private cannot be accessed from outside the class or even by derived classes.

Example:

private_example.cpp
1#include <iostream>
2
3class Person {
4private:
5 std::string name;
6 int age;
7
8public:
9 void setName(std::string n) {
10 name = n;
11 }
12
13 void setAge(int a) {
14 age = a;
15 }
16
17 void display() {
18 std::cout << "Name: " << name << ", Age: " << age << std::endl;
19 }
20};
21
22int main() {
23 Person person1;
24 // person1.name = "John"; // Error: 'name' is private
25 // person1.age = 30; // Error: 'age' is private
26
27 person1.setName("John");
28 person1.setAge(30);
29 person1.display();
30
31 return 0;
32}
Output
Name: John, Age: 30

Explanation: Here, the name and age variables are private. They cannot be accessed directly from main(). Instead, public member functions setName() and setAge() are used to modify these private members.

Protected Access Modifier

The protected access specifier is similar to private, but it allows derived classes to access the protected members. This is useful when you want to restrict access to certain members from outside the class hierarchy but allow them to be accessible by subclasses.

Example:

protected_example.cpp
1#include <iostream>
2
3class Base {
4protected:
5 int value;
6
7public:
8 void setValue(int v) {
9 value = v;
10 }
11};
12
13class Derived : public Base {
14public:
15 void display() {
16 std::cout << "Value: " << value << std::endl; // Accessible in derived class
17 }
18};
19
20int main() {
21 Base baseObj;
22 // baseObj.value = 10; // Error: 'value' is protected
23
24 Derived derivedObj;
25 derivedObj.setValue(20);
26 derivedObj.display();
27
28 return 0;
29}
Output
Value: 20

Explanation: In this example, the value variable in the Base class is protected. It cannot be accessed directly from main(), but it can be accessed within the Derived class.

Default Access

If no access specifier is explicitly specified for a member, it defaults to the access level of its containing class. For classes defined at global scope, members default to public. For nested classes, members default to private.

Example:

default_access.cpp
1#include <iostream>
2
3class Outer {
4 int x; // Default is private
5
6public:
7 void setX(int val) {
8 x = val;
9 }
10
11 void display() {
12 std::cout << "x: " << x << std::endl;
13 }
14};
15
16int main() {
17 Outer obj;
18 // obj.x = 10; // Error: 'x' is private
19 obj.setX(10);
20 obj.display();
21
22 return 0;
23}
Output
x: 10

Explanation: The variable x in the Outer class does not have an explicit access specifier, so it defaults to private. It can only be accessed through public member functions.

Getter/Setter Pattern

The getter/setter pattern is a common practice used with private members to provide controlled access and modification of data. This pattern helps enforce encapsulation by allowing validation or transformation of data before setting it.

Example:

getter_setter.cpp
1#include <iostream>
2#include <string>
3
4class Person {
5private:
6 std::string name;
7 int age;
8
9public:
10 void setName(std::string n) {
11 if (!n.empty()) {
12 name = n;
13 } else {
14 std::cout << "Invalid name." << std::endl;
15 }
16 }
17
18 std::string getName() const {
19 return name;
20 }
21
22 void setAge(int a) {
23 if (a > 0 && a < 120) {
24 age = a;
25 } else {
26 std::cout << "Invalid age." << std::endl;
27 }
28 }
29
30 int getAge() const {
31 return age;
32 }
33};
34
35int main() {
36 Person person1;
37 person1.setName("Alice");
38 person1.setAge(25);
39
40 std::cout << "Name: " << person1.getName() << ", Age: " << person1.getAge() << std::endl;
41
42 // Attempt to set invalid values
43 person1.setName("");
44 person1.setAge(130);
45
46 return 0;
47}
Output
Name: Alice, Age: 25
Invalid name.
Invalid age.
Name: Alice, Age: 25

Explanation: The Person class uses getter and setter methods to control access to its private members. This pattern ensures that only valid data is stored in the object.

Practical Example

Let's create a practical example that combines the use of public, private, protected, and the getter/setter pattern.

practical_example.cpp
1#include <iostream>
2#include <string>
3
4class Employee {
5private:
6 std::string name;
7 int id;
8
9protected:
10 double salary;
11
12public:
13 void setName(std::string n) {
14 if (!n.empty()) {
15 name = n;
16 } else {
17 std::cout << "Invalid name." << std::endl;
18 }
19 }
20
21 std::string getName() const {
22 return name;
23 }
24
25 void setId(int i) {
26 if (i > 0) {
27 id = i;
28 } else {
29 std::cout << "Invalid ID." << std::endl;
30 }
31 }
32
33 int getId() const {
34 return id;
35 }
36
37 void setSalary(double s) {
38 if (s >= 0) {
39 salary = s;
40 } else {
41 std::cout << "Invalid salary." << std::endl;
42 }
43 }
44
45 double getSalary() const {
46 return salary;
47 }
48
49 void display() const {
50 std::cout << "Name: " << name << ", ID: " << id << ", Salary: $" << salary << std::endl;
51 }
52};
53
54class Manager : public Employee {
55public:
56 void bonus(double amount) {
57 if (amount > 0) {
58 salary += amount;
59 } else {
60 std::cout << "Invalid bonus amount." << std::endl;
61 }
62 }
63};
64
65int main() {
66 Manager manager1;
67 manager1.setName("John");
68 manager1.setId(101);
69 manager1.setSalary(50000);
70
71 manager1.display();
72 manager1.bonus(5000);
73 manager1.display();
74
75 return 0;
76}
Output
Name: John, ID: 101, Salary: $50000
Name: John, ID: 101, Salary: $55000

Explanation: The Employee class has private members for name and id, a protected member for salary, and public getter/setter methods to control access. The Manager class inherits from Employee and can access the protected salary member directly, as well as use its own bonus() method to modify the salary.

Summary

Access ModifierAccessibility
PublicEverywhere
PrivateWithin Class
ProtectedWithin Class & Derived Classes
  • Public: Members are accessible from anywhere.
  • Private: Members are only accessible within their own class.
  • Protected: Members are accessible within their own class and by derived classes.

Using access modifiers effectively helps in encapsulating data, preventing unauthorized access, and maintaining the integrity of the program. The getter/setter pattern further enhances control over data manipulation.

What's Next?

Now that you have a solid understanding of access modifiers and the getter/setter pattern, it's time to dive deeper into Encapsulation. Encapsulation is the process of bundling the data (attributes) and methods (functions) that operate on the data into a single unit or class. It also restricts direct access to some of an object's components, which can prevent the accidental modification of data.

In the next topic, we will explore how encapsulation works in C++ and why it is essential for building robust and maintainable software systems.


PreviousDestructorsNext Encapsulation

Recommended Gear

DestructorsEncapsulation