C++ - Access Specifiers

In C++, access specifiers are keywords used to specify the visibility and accessibility of class members (data members and member functions) within a class hierarchy. There are three access specifiers: public, private, and protected.

Public Access Specifier:

The public access specifier allows the class members to be accessed from anywhere in the program. Public members are accessible not only from within the class but also from outside the class, including other classes and functions. This specifier is commonly used for the interface or public API of a class.

class MyClass {
public:
    int publicData;  // Public data member
    void publicMethod() {
        // Public member function
    }
};

In this example, publicData and publicMethod() are accessible from anywhere in the program, including outside the class.

Private Access Specifier:

The private access specifier restricts the access to class members only within the class itself. Private members cannot be accessed directly from outside the class or even from derived classes. This specifier is commonly used to encapsulate the internal implementation details of a class and prevent direct manipulation of class internals.

class MyClass {
private:
    int privateData;  // Private data member
    void privateMethod() {
        // Private member function
    }
};

In this example, privateData and privateMethod() can only be accessed from within the class MyClass.

Protected Access Specifier:

The protected access specifier allows class members to be accessed within the class itself and its derived classes. Protected members are similar to private members in that they are not accessible from outside the class hierarchy, but they can be accessed by derived classes. This specifier is used to provide access to derived classes while still encapsulating the members from the outside world.

class MyBaseClass {
protected:
    int protectedData;  // Protected data member
    void protectedMethod() {
        // Protected member function
    }
};
class MyDerivedClass : public MyBaseClass {
public:
    void derivedMethod() {
        protectedData = 10;  // Accessing protected member from derived class
        protectedMethod();  // Accessing protected member function from derived class
    }
};

In this example, protectedData and protectedMethod() can be accessed within the derived class MyDerivedClass because it inherits from MyBaseClass.

#include <iostream>
class BaseClass {
public:
    int publicData;
    void publicMethod() {
        std::cout << "BaseClass::publicMethod() called" << std::endl;
    }
private:
    int privateData;
    void privateMethod() {
        std::cout << "BaseClass::privateMethod() called" << std::endl;
    }
protected:
    int protectedData;
    void protectedMethod() {
        std::cout << "BaseClass::protectedMethod() called" << std::endl;
    }
};
class DerivedClass : public BaseClass {
public:
    void derivedMethod() {
        publicData = 10;             // Accessible (public data member)
        publicMethod();              // Accessible (public member function)
        protectedData = 20;          // Accessible (protected data member)
        protectedMethod();           // Accessible (protected member function)
    }
};
int main() {
    BaseClass baseObject;
    baseObject.publicData = 5;       // Accessible (public data member)
    baseObject.publicMethod();       // Accessible (public member function)
    DerivedClass derivedObject;
    derivedObject.derivedMethod();   // Accessing inherited members from the derived class
    return 0;
}

In this example, we have a base class called BaseClass and a derived class called DerivedClass that inherits from BaseClass.

  • The BaseClass has members with different access specifiers:
  • publicData and publicMethod() are declared as public members, so they can be accessed from anywhere.
  • privateData and privateMethod() are declared as private members, so they can only be accessed within the class itself.
  • protectedData and protectedMethod() are declared as protected members, so they can be accessed within the class and its derived classes.
  • The DerivedClass inherits the members of BaseClass and can access the inherited members based on their access specifiers. In the main() function, we create objects of both classes and demonstrate the accessibility of the members.