Introduction:
One essential aspect of object-oriented programming in C++ is encapsulation, which allows for the hiding of internal object details like data members, preventing program functions from directly interacting with an object's internal structure, including data members and member functions.
Access modifiers establish constraints on the accessibility of class methods. Within C++, access modifiers are known as visibility modes and encompass private, public, and protected. The upcoming segments of this guide will delve deeper into the specifics of each of these visibility modes.
By employing visibility modes, we can establish the inheritance behavior of the derived class from the base class and define which base class members can be accessed by the derived class. These modes, also referred to as access specifiers, play a crucial role in determining the accessibility and visibility level of class members.
When instances of the derived class are able to make use of a method from the base class, access specifiers are commonly applied in the process of inheritance. The typical syntax for implementing an access specifier when a subclass is derived from a superclass is as follows:
class Base {
// base class content
};
class Derived: access_specifier Base {
// child's class content
};
In the provided code snippet, the access_specifier indicates which members from the base class will be inherited and accessible in the derived class. The code includes a base class named Base and a derived class named Derived.
Multiple public, protected, or private sections are allowed within C++ classes. The following code showcases the utilization of visibility modes within a class:
class base {
public:
// public members place
protected:
// protected members place
private:
// private members place
};
In the code snippet provided, the fundamental class base is divided into multiple sections using access specifiers.
NOTE: The private mode is taken into account by default if no visibility mode is specified.
The Private Members:
When a subclass extends a superclass using private inheritance, all elements of the superclass - including public, private, and protected members - are transformed into private members within the subclass.
The sole functions permitted to access these members beyond the derived class are the member functions within the derived class or the friend functions.
When the derived class's access mode is configured as private, the subsequent block diagram illustrates the inheritance of base class data members.
The private variable can solely be accessed by member functions within the base class exclusively, evident from the provided diagram since it is classified as private within the base class. Consequently, it remains inaccessible in the derived class. The base class's protected variable b and the public variable c will be converted to private in the derived class, restricting access solely to its member functions.
A straightforward practical scenario can help clarify the importance of using each access specifier. Consider a situation where you intend to post a status on a social media platform, but you have specific requirements and restrictions on who can view this particular status. In this case, if you opt to make this status concealed from other users or restrict it to be visible solely to yourself, you are essentially implementing the concept of the private access specifier.
Example:
Exploring a specific scenario can provide a deeper understanding of the concept of private visible mode and the constraints it enforces.
class Parent
{
private:
int x1;
protected:
int x2;
public:
int x3;
};
class Child: private Parent
{
};
In the provided code snippet, the base class members within the derived class have been set as private due to the private visibility mode. If an instance of the derived class attempts to retrieve these members from outside the derived class, it will result in an error being triggered.
Let's execute another C++ program to demonstrate the behavior of the private access specifier when an instance of the base class attempts to access a private data member x beyond the class scope.
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:
Since external access to private class members is restricted, attempting to retrieve them outside the class will result in a compile-time error for the program in question.
Nevertheless, through utilizing the public member functions of the base class, we are able to indirectly retrieve the private data members.
Accessibility:
The accessibility of private mode can be succinctly described 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 attributes of the base class retain their respective access levels as public, private, and protected attributes in the derived class when we extend a subclass from the superclass with public inheritance. All attributes of the superclass stay reachable under public inheritance.
The child class along with all other classes can utilize the parent's public members. Access to the protected base class members is limited to the derived class and its inherited classes. However, the child class is restricted from accessing the private members.
When the access mode of the derived class is defined as public, the subsequent diagram illustrates the inheritance of data members from the base class.
As depicted in the image above, the private variable belongs to the private type and is exclusively accessible by the member functions of the base class. Consequently, it remains inaccessible in the derived class. The public variable remains accessible to all, including the child class. The protected variable 'b' of the base class remains protected in the derived class, accessible only within the derived class and its inheriting classes.
When you update your status on a social media platform to be visible to everyone online, you are following the concept of the "Public access specifier."
Example:
To gain a deeper insight into the idea of public exposure mode and the constraints it enforces, let's examine an illustration:
class Parent
{
private:
int x1;
protected:
int x2;
public:
int x3;
};
class Child: public Parent
{
};
In the example provided, the ```
class Base {
// base class content
};
class Derived: access_specifier Base {
// child's class content
};
Let's consider another C++ program to demonstrate the functionality of the public access specifier when an instance of a base class needs to access a public data member x externally 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 code snippet provided, the attribute x is defined as public, enabling access from both within and outside the class.
### Accessibility:
The accessibility of the public mode can be succinctly described as:
| 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 subclass extends its superclass using the protected visibility mode, all attributes of the superclass become protected attributes of the subclass. Consequently, only the subclass and its methods are granted access to these attributes. Any subclasses inheriting from this subclass will also be able to access these attributes, which are similarly inheritable.
When the derived class's access mode is configured as protected, the subsequent diagram illustrates the inheritance of base class data members.
As depicted in the image above, the private variable belongs to the private type, restricting its accessibility solely to the member functions of the base class. Consequently, it remains inaccessible in the derived class. The public variable "a" can only be accessed by the inherited subclasses of this derived class, where it transitions to a protected status. The protected variable "b" of the base class maintains its protected status in the derived class, remaining accessible exclusively within the derived class and its inherited subclasses.
Using the practical scenario of modifying your status on a social networking application mentioned previously; suppose you wish for your status to be viewable exclusively by your circle of friends. Here, you are applying the "Protected access specifier" principle.
### Example:
Exploring a specific scenario can provide a deeper understanding of the concept of protected visibility and the constraints it enforces.
class Parent
{
private:
int x1;
protected:
int x2;
public:
int x3;
};
class Child: protected Parent
{
};
In the provided code snippet, the access levels of the Parent class's protected and public members will be inherited as protected members in the Child class due to the protected visibility mode.
The public variable x3 in the Child class will inherit the same accessibility as the protected member from the parent class. However, the private variable x1 will not be accessible in the Child class. Both the protected variable x2 and the public variable x3 will be inherited from the Parent class with accessibility maintained in the Child class.
Let's consider another example in C++ to demonstrate the functionality of protected access specifiers when an instance of a base class attempts to access a protected data member outside the class within 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 code snippet provided, the instance variable x is specified as protected, granting access to it by any subclass (also known as a derived class) of the parent class.
### Accessibility:
The accessibility of protected mode can be summarized in the following manner:
| 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.