C++ Encapsulation

Encapsulation is one of the four fundamental principles of object-oriented programming (OOP), along with inheritance, polymorphism, and abstraction. In C++, encapsulation refers to the process of hiding the implementation details of a class from the outside world, and exposing only a public interface for interacting with the class. This allows the class to be self-contained and to protect its internal state from being modified or accessed by unauthorized parties.

Why Use Encapsulation?

Encapsulation has several benefits:

  • It promotes data security by protecting the internal state of the class from being modified or accessed by unauthorized parties.
  • It allows the class to be self-contained, making it less dependent on other classes and making it easier to change or update the class’s implementation without affecting other parts of the program.
  • It makes the class more robust and less prone to errors, by preventing the internal state from being corrupted by external code.
  • It makes the class more reusable, by allowing it to be used in different parts of the program without requiring the user to know the details of its implementation.

Implementing Encapsulation in C++

In C++, encapsulation is implemented using access specifiers, which are keywords used to specify the accessibility or visibility of class members (variables and functions) and the class itself. There are three types of access specifiers in C++: public, protected, and private.

Public

The public access specifier is the most permissive access level. Members and functions declared as public can be accessed from anywhere, both inside and outside the class. This means that any function or variable declared as public can be accessed by any other function or variable, regardless of where it is located in the program.

For example, consider the following class:

class MyClass {
public:
    int myInt;
    void myFunction() {
        cout << "This is a public function" << endl;
    }
};

In this example, the myInt variable and myFunction() function are both declared as public. This means that they can be accessed and modified from outside the class, as shown in the following code:

int main() {
    MyClass myObject;
    myObject.myInt = 5;
    myObject.myFunction();
    return 0;
}

Protected

The protected access specifier is less permissive than public, but more permissive than private. Members and functions declared as protected can be accessed from within the class and from derived classes, but not from outside the class. This means that any function or variable declared as protected can be accessed by any other function or variable that is located in the same class or in a derived class, but not by any function or variable located outside the class.

For example, consider the following class:

class MyBase {
protected:
    int myInt;
    void myFunction() {
        cout << "This is a protected function" << endl;
}
};

class MyDerived : public MyBase {
public:
void accessProtected() {
myInt = 5;
myFunction();
}
};

In this example, the myInt variable and myFunction() function are both declared as protected in the MyBase class. This means that they can be accessed and modified from within the class and from the derived class MyDerived, but not from outside the class. The accessProtected() function in the MyDerived class is able to access the protected members of the MyBase class, as shown in the following code:

int main() {
    MyDerived myObject;
    myObject.accessProtected();
    return 0;
}

Private

The private access specifier is the most restrictive access level. Members and functions declared as private can only be accessed from within the class. This means that any function or variable declared as private can only be accessed by other functions or variables that are located within the same class, and not by any function or variable located outside the class or in a derived class.

For example, consider the following class:

class MyClass {
private:
    int myInt;
    void myFunction() {
        cout << "This is a private function" << endl;
    }
};

In this example, the myInt variable and myFunction() function are both declared as private. This means that they can only be accessed and modified from within the class, and not from outside the class or from a derived class. Attempting to access or modify a private member from outside the class will result in a compile-time error, as shown in the following code:

int main() {
    MyClass myObject;
    myObject.myInt = 5; //compile-time error
    myObject.myFunction(); //compile-time error
    return 0;
}

It should be noted that the default access level for class members is private in C++, so if no access specifier is specified, the members are considered private by default.

Getter and Setter Functions

Encapsulation can also be achieved in C++ using getter and setter functions. These are public functions that are used to access and modify the internal state of a class. The getter function, also known as an accessor function, is used to retrieve the value of a private member, while the setter function, also known as a mutator function, is used to change the value of a private member. By using getter and setter functions, the internal state of the class can be protected from being accessed or modified directly, while still allowing the class to be interacted with from outside the class.

For example, consider the following class:

class MyClass {
private:
    int myInt;
public:
    int getMyInt() {
        return myInt;
    }
    void setMyInt(int val) {
        myInt = val;
    }
};

In this example, the myInt variable is declared as private, and can only be accessed or modified through the getMyInt() and setMyInt() functions, which are declared as public. This allows the internal state of the class to be protected, while still allowing other parts of the program to interact with the class. The following code shows how the class can be used in a program:

int main() {
    MyClass myObject;
    myObject.setMyInt(5);
    cout << myObject.getMyInt() << endl; // Outputs: 5
    return 0;
}

In this example, the setMyInt() function is used to change the value of the myInt variable to 5, and the getMyInt() function is used to retrieve the value of the myInt variable and output it to the console. This allows the internal state of the class to be protected, while still allowing the class to be interacted with from outside the class.

It should be noted that, this approach can be improved by overloading the operator and use the class variable directly like obj.myInt = 5, instead of using setMyInt(5).

Leave a Reply

Your email address will not be published. Required fields are marked *