Encapsulation in C++

C++, being a versatile programming language, has got various Object-Oriented Programming features. Encapsulation is one of the important OOP features provided by C++, it enables the programmer to incorporate data members and methods/functions into a single constituent. That single unit or constituent is class, and this entire process is known as encapsulation.

Let’s take a real-life example:

In an IT company, a software engineer from a different team is working on a project that needs entry from the database. The engineer then needs to ask for permission from the database engineer to access data from the database, since there is a restriction in the data for the different team members. This is what encapsulation is.

The data in the database is not visible for the software engineer as it is the data for another team that can manipulate everything that is wrapped under “database department”.

Types of Encapsulation in C++

In C++ there are three different ways to implement encapsulation:

1. Member variable encapsulation
2. Function encapsulation
3. Class encapsulation

As the names clearly depict, in member variable encapsulation all the data variables or data members are declared private. Whereas, in Function Encapsulation, some of the functions and constructors are declared private. While in Class Encapsulation, the entire class is declared as private (usually done in the case of multiple classes).

C++ Data Encapsulation Examples

Example 1:

#include <iostream>
using namespace std;
class Sum {
  public:
    // Data Variables required for adding two numbers
    int num1;
    int num2;
    
    //constructor to initialize the two numbers
    Sum (int x, int y)
    {
        num1=x;
        num2=y;
    }

    // Function to calculate sum
    int get() {
      return num1 + num2;
    }
};

int main() {
  // Create object of Sum class
  Sum obj(6,9);

  // Call get() function
  cout << "Sum = " << obj.get();

  return 0;
}

Output:

Sum = 15

…Program finished with exit code 0
Press ENTER to exit console.

In this example, we needed two variables num1 and num2 along with functions get() and constructor to calculate the sum of two numbers. Hence, we combined all these data members and variables into a single Sum class.

Note: In the above example as we declared every data member and functions as public it is also accessible to the other classes. Therefore, this is not data hiding.

Encapsulation refers to combining the related variables and functions together, which can be used to achieve data hiding. Hence, encapsulation is not always data hiding.

Example 2:

In Data Hiding, there is restricted access to the data members and functions. Usage of access specifiers helps us achieve data hiding. For example,

// Program to calculate the sum of two numbers
#include <iostream>
using namespace std;

class Sum {
  private:
    // Data Variables required for adding two numbers
    int num1;
    int num2;
    //Function to set the two numbers

  public:
    void set(int x, int y)
    {
        num1=x;
        num2=y;
    }
    // Function to calculate sum
    int get() {
      return num1 + num2;
    }
};

int main() {
  // Create object of Sum class
  Sum obj ;
  obj.set(6,9);
  // Call get() function
  cout << "Sum = " << obj.get();
  return 0;
}

Output:

Sum = 15

…Program finished with exit code 0
Press ENTER to exit console.

In the above example, we declared the data variables private and hence we could not access it from the main() method as it is outside the class. For that, we had to create a set() function and pass the values to the class members. Since the data is hidden, we can not simply use constructors to initialize the variables.

Role of Access Specifiers in C++

As seen from the above examples, in C++ we can use access specifiers or modifiers to implement encapsulation and further achieve data hiding which will help the programmers in many different ways.

There are 3 types of access specifiers according to which one can implement encapsulation:

1. Public:

Member functions or methods can be declared as public so that they can manipulate the data members.

2. Private:

The data members should be declared as private so that they can not be accessed by members from different classes. By default, all members of the class are declared private.

3. Protected:

This access specifier is only used in case of inheritance, we will learn about this in a different tutorial.

Let’s take an example:

class example {
  public:       
    int num1;   // Public data member
  private:      
    int num2;   // Private data member
};

int main() {
  example obj;
  obj.num1 = 5;  // Allowed 
  obj.num2 = 7;  // Will throw an error
  return 0;
}

Output:

main.cpp:11:7: error: ‘int example::num2’ is private within this context
  obj.num2 = 7// Will throw an error
      ^~~~
main.cpp:5:9: note: declared private here
    int num2;   // Private data member
        ^~~~

Clearly, we can now infer those data members declared as private are not accessible from the outside world. When we used an object to pass the value it threw an error, which shows that the main() method is restricted to access that private data member.

Benefits of C++ Encapsulation

1. In C++, encapsulation helps to combine the related members into a single class, making the code look cleaner and increasing readability. 

2. The get() and set() functions provide read-only and write-only accessibility to the user. Hence, keeping the data secure. 

3. The bundling of the data eases out the development in general. The testing, debugging, and execution of these bundles can be done individually, which will not affect the other parts. 

4. Data hiding is a good way to keep the data secure from the outside world. Hence, improving the security of the code even further. 

5. Encapsulation provides us with efficient control of the data as we can alter one part of the code without affecting the other. 

Designing Strategy

By learning encapsulation you will get a good habit of defining data members as private. This way we can keep our data secure from the outside world. This technique is mostly applied to member variables, but we can apply it to member functions as well. In this way, we can use encapsulation regularly. 

Difference between Data Abstraction and Encapsulation

Data Abstraction Encapsulation
Data Abstraction solves the problems by proposing a design. Encapsulation implements the proposed design and solves the problems.
Data Abstraction hides the details of the code and only displays what the user needs. Encapsulation helps in combining the data members including variables and functions into a single unit called class.
In Abstraction, the use of classes and objects increases the security of the code. In Encapsulation, the use of access specifiers helps to restrict access to the data from the outside world.
The hiding of the implementation is done in Abstraction. Using Encapsulation, the information can be kept hidden. 

Summary

In this article from TechVidvan, we talked about encapsulation and how it is helpful with a real-life example. We went further to discuss the examples of how one can implement encapsulation.

Through those examples, we understood the concept of data hiding and how it is different from encapsulation. We also threw light upon the advantages of encapsulation and how it would be good to practice encapsulation in our codes. 

Keep Learning!