Introduction:
One of the key components of object-oriented programming in C++ is data hiding , which enables us to conceal internal object characteristics, such as data members , and prohibits program functions from directly accessing an object's internal representation , data members , and member functions .
Access modifiers define the limitations on access to class member functions . In C++, visibility modes , such as private, public , and protected , are also referred to as access modifiers . In the following sections of this article, we will examine each of them in further detail.
We can determine how the derived class will inherit the base class and which base class members of the derived class will be able to access by using visibility modes. Since they are used to specify the accessibility and visibility level of class members, they are known as visibility mode or access specifier .
When the derived class objects can utilize a member function in the base class, access specifiers are mostly employed in inheritance. The following is the standard syntax for utilizing an access specifier when a child class is derived from the base class:
class Base {
// base class content
};
class Derived: access_specifier Base {
// child's class content
};
In the code above, the access_specifier tells us which base class members will be obtained and made accessible by the derived class . There is also a base class called Base and a derived class called Derived .
Multiple public, protected , or private parts are permissible in C++ classes. The code below demonstrates how visibility modes can be used in a class:
class base {
public:
// public members place
protected:
// protected members place
private:
// private members place
};
In the code above, the basic class base is separated into several pieces by access specifiers.
NOTE: The private mode is taken into account by default if no visibility mode is specified.
The Private Members:
When a child class inherits from its parent class in the private visibility mode, all of the base class's members- public, private , and protected members -become private in the derived class .
The only functions that have access to these members outside of the derived class are the member functions of the derived class or the friend functions.
When the derived class access mode is set to private , the following block diagram can demonstrate how data members of the base class are inherited.
The private variable is only available by member functions within the base class itself, as you can see from the image above because it is of the private type within the base class . As a result, it is not accessible in the derived class . The protected variable b and the public variable c of the base class will change to private in the derived class, and only its member functions will have access to them.
A very simple real-life example will assist us in understanding when each access specifier is necessary. Let's say you want to update your status on a social networking app, but you have some criteria and limitations on who can see this status online. Therefore, if you want this status to be hidden from others or to be visible "only for me", you are adhering to the private access specifier notion.
Example:
Let's look at a case study to better grasp the idea of private visible mode and the limitations it imposes:
class Parent
{
private:
int x1;
protected:
int x2;
public:
int x3;
};
class Child: private Parent
{
};
In the code above, all of the base class members in the derived class have been made private because the visibility mode is private . When an object of a derived class tries to access these members outside of the derived class, an error is raised .
Let's run one more C++ program to show how the private access specifier functions when an object of the base class tries to access a private data member x outside of the class.
class base
{
// data member is private
private:
int x;
//function of public member
public:
void fun()
{
// the base class's member functions can access private data
return 2 * x;
}
};
// main function
int main()
{
// creating a class object
base obj;
// attempting to directly access confidential data of other class members
obj.x = 78;
cout<<obj.fun() <<endl;
}
Output:
Explanation:
As we are not permitted to directly access the private data of members of a class from outside the class , the output of the aforementioned program will be a compile-time error .
However, by using the base class's public member operations, we can indirectly access the private data members.
Accessibility:
The private mode's accessibility can be summed up as follows:
| Accessibility | Private mode |
|---|---|
| Same class | Yes |
| Derived class | No |
| Other class | No |
| Anywhere in the program | No |
The members specified by the private access specifier are exclusively reachable inside the same class; they are not reachable within any derived classes or other classes in the program.
The Public Members:
The public, private , and protected members of the base class remain public, private , and protected members of the derived class when we inherit a child class from the parent class in public visibility mode . All members of the parent class remain accessible in the public visibility mode .
The child's class and all other classes can access the parent's public members . Only the derived class and its inherited classes have access to the protected base class members. Although, the child class cannot access the private members .
When the derived class access mode is set to public , the following block diagram can demonstrate how base class data members are inherited.
As you can see from the image above, the private variable is of the private type and is, therefore, only accessible by the base class member functions. As a result, it is not available in the derived class . The public variable will continue to be available to everyone, including the child's class . The base class's protected variable b will continue to be protected in the derived class and will only be available within the derived class and its inherited classes .
Using the above real-world example of updating your status on a social media app as an example, if you want your status to be publicly viewable online, you are adhering to the "Public access specifier" idea.
Example:
To further understand the concept of public exposure mode and the limitations it imposes, let's look at an example:
class Parent
{
private:
int x1;
protected:
int x2;
public:
int x3;
};
class Child: public Parent
{
};
In the code above, the protected variable x2 will be inherited from the Parent class and accessible in the Child class and its inherited classes , just as the public variable x3 will be inherited from the Parent class and accessible in the Child class and other classes, but the private variable x1 will not be accessible in the Child class .
Let's take another C++ program to show how the public access specifier functions when an object of a base class wants to access a public data member x outside of the class in the main function .
#include <iostream> // Add the headers required for input and output activities.
using namespace std; // For cout and endl, include the std namespace.
class base
{
public:
int x;
int fun() // Change the function's return type to int.
{
return 2 * x;
}
};
int main()
{
base obj;
obj.x = 8;
cout<<obj.x<<endl;
cout<<obj.fun();
return 0; // After the main function, provide a return statement.
}
Output:
In the program above, the data member x is designated as public , allowing access from inside and outside of the class.
Accessibility:
The public mode's accessibility can be summed up as follows:
| Accessibility | Private mode |
|---|---|
| Same class | Yes |
| Derived class | Yes |
| Other class | Yes |
| Anywhere in the program | Yes |
Users have access to the members defined under the public access specifier everywhere within the same class, derived classes, in any other class, or even outside the class.
The Protected Members:
When a child class is derived from its parent class in the protected visibility mode , all of the base class's members are turned into protected members of the derived class. As a result, only the derived class and its member functions can now access these members. The inherited subclasses of this derived class will have access to these members, which are likewise inheritable.
When the derived class access mode is set to protected , the following block diagram can demonstrate how data members of the base class are inherited.
As you can see from the image above, the private variable is of the private type and is, therefore, only accessible by the base class member functions . As a result, it is not available in the derived class . Only the inherited subclasses of this derived class will have access to the public variable a , which will become protected in the derived class . The base class's protected >variable b will continue to be protected in the derived class and will only be available within the derived class and its inherited classes .
Using the real-world example of updating your status on a social media app we used earlier; let's say you want your status to only be visible to your friends and friends. In this case, you are adhering to the "Protected access specifier" concept.
Example:
Let's look at a case study to better grasp the protected visibility mode notion and the limitations it imposes:
class Parent
{
private:
int x1;
protected:
int x2;
public:
int x3;
};
class Child: protected Parent
{
};
In the code above, the protected and the public members of the Parent class will change to the protected members of the Child class since the visibility mode is protected.
The public variable x3 will also be inherited from the parent class as the protected member and will be accessible in the Child class , but the private variable x1 will not be. Both the protected variable x2 and the public variable x3 will be inherited from the Parent class and will be accessible in the Child class .
Let's take another C++ program to show how protected access specifiers works when an object of a base class tries to access a protected data member outside of the class in the main function .
#include <iostream>
using namespace std;
class base
{
private:
int x;
public:
void setX(int value)
{
x = value;
}
int getX()
{
return x;
}
protected:
int fun()
{
return 3 * x;
}
};
int main()
{
base obj;
obj.setX(8);
cout<<obj.getX() <<endl;
cout<<obj.fun() <<endl;
return 0;
}
Output:
Explanation:
In the program above, the data member x is designated as protected, allowing any subclass (derived class) of the base class to access it.
Accessibility:
The protected mode's accessibility can be summed up as follows:
| Accessibility | Private mode |
|---|---|
| Same class | Yes |
| Derived class | Yes |
| Inherited subclasses of the derived class | Yes |
| Other class | No |
| Anywhere in the program | No |
The derived class and its inherited classes can access the members defined under the protected access specifier.
Differences between Private, Public, and Protected in C++:
| Private | Public | Protected |
|---|---|---|
| Only the functions inside the base class can access class members that have been designated as private. | The participants of the class that have been made public are accessible from anywhere. | The base class and its derived classes allow access to class members that have been designated as protected. |
| The keywordprivateis used to declare private members, followed by thecolon (:) symbol. | Thekeyword publicis used to declare members, followed by the colon (:) symbol. | Membersthat are protected are identified by using the word protected and the colon (:) character. |
| Private membersare not passed down across classes. | In a class,public membersmay be inherited. | In a class,protected memberscan be inherited. |
| It offers its data members the highest level of protection. | It offers no security at all for the data it holds. | Compared to private access specifier, it offers less security. |
| Afriend functioncan be used to access private members. | Access to public members is possible both with and without the aid of the friend feature. | Protected members are inaccessible outside the class and cannot be accessed by the friend function, but they may be accessed by any subclass (derived class) of that class. |
The three visibility modes mentioned above can be summed up as follows in C++:
class Base {
public:
int x;
protected:
int y;
private:
int z;
};
class PublicDerived: public Base {
// x is accessible in the PublicDerived class and is public.
// y is accessible and protected in the PublicDerived class.
// Since z belongs to the base class as a private member, it is not accessible through PublicDerived.
};
class ProtectedDerived: protected Base {
// In the ProtectedDerived class, x is accessible and protected.
// y is accessible and protected in the ProtectedDerived class.
// Due to the fact that z is a private member of the base class, it is not available via ProtectedDerived.
};
class PrivateDerived: private Base {
// Only the member functions of the PrivateDerived class have access to the private variable x.
// Only the member functions of the PrivateDerived class have access to the private variable y.
// Given that z is a private member of the base class, it is not available via PrivateDerived.
};
Conclusion:
- The availability of the class members ( data members and member functions ) outside of that class has been determined using access specifiers.
- Access specifiers are used to define whether the objects of the derived class can use a member function in the base class. It is known as accessibility in inheritance .
- In C++, there are three different sorts of access specifiers: private, public , and protected . If no visible mode is defined or requested, the private mode is taken into account by default.
- If the class's members are designated as public, then anyone can access them.
- When class members are marked as protected, the base and any derived classes can access them.
- When a class's members are designated as private , only other members of the base class and friend functions have access to them.
- Compared to public and protected access specifiers , the private access specifier offers its data member's higher security.
- Declaring your class attributes as private as frequently as possible is regarded as best practice because it will help increase data security.
- Access modifiers enable us to regulate which portion of a program can access a class's members, so they are mostly used for data hiding and encapsulation . So that data misuse can be avoided.