Access Specifiers In C++ Inheritance

In C++, access specifiers are keywords that define the accessibility of class members (attributes and methods) to different parts of a program. There are three main access specifiers in C++:

  • public: Members are accessible from anywhere.
  • protected: Members are accessible within the class, derived classes, and friends, but not outside.
  • private: Members are accessible only within the class itself and friends class, not outside or in derived classes.

Access Specifiers in Inheritance

When you create a derived class by inheriting from a base class, the access level of the members from the base class can change depending on the type of inheritance used. In C++, there are three types of inheritance:

  • Public Inheritance
  • Protected Inheritance
  • Private Inheritance

By default Access Specifiers in Inheritance

Let’s explore how each access specifier works in inheritance.

1. By Default Access Specifiers (Private)

When a class is inherited without specifying an access specifier is called By default access specifier.

  • In class, the default inheritance is private, meaning all public and protected members of the base class will become private in the derived class unless explicitly specified otherwise.

Note: In a class, members are private by default if within class access specifier is not defined.

Inherited (Child) Class as Private Access Specifier

  • Public members  and Protected members of the Parent class will also become private in Child, meaning they are not accessible outside the Child class, not even from further derived classes.
  • Private members of the Parent class are inaccessible in the any Child class or outside the class.

Derived Class private - Access Specifiers in Inheritance

Example 1: The derived  class is a private access specifier

#include <iostream>
using namespace std;class Parent {
public:
int a; // Public member
protected:
int b; // Protected member
private:
int c; // Private member
};

class Child : private Parent {
// Inherits a, b, c from Parent with private inheritance
// a (public in Parent) becomes private in Child
// b (protected in Parent) becomes private in Child
// c (private in Parent) is not accessible in Child

};

int main() {
Child obj;

// obj.a = 5; // Error: ‘a’ is private in Child, cannot be accessed outside the class
// obj.b = 10; // Error: ‘b’ is private in Child, cannot be accessed outside the class
// obj.c = 20; // Error: ‘c’ is private in Parent, cannot be accessed in Child

return 0;
}

Example 2:  derived  class is private access specifier (Use Case)

#include <iostream>
using namespace std;class Parent {
public:
int a; // Public member
protected:
int b; // Protected member
private:
int c; // Private member
};

class Child : private Parent {
// Inherits a, b, c from Parent with private inheritance
// a (public in Parent) becomes private in Child
// b (protected in Parent) becomes private in Child
// c (private in Parent) is not accessible in Child
public:
void setValues() {
a = 5; // OK: ‘a’ is now private in Child, but accessible inside Child
b = 10; // OK: ‘b’ is now private in Child, but accessible inside Child
// c = 20; // Error: ‘c’ is private in Parent, cannot be accessed in Child
}

void display() {
cout << “a: ” << a << “, b: ” << b << endl;
}
};

int main() {
Child obj;

// obj.a = 5; // Error: ‘a’ is private in Child, cannot be accessed outside the class
// obj.b = 10; // Error: ‘b’ is private in Child, cannot be accessed outside the class
// obj.c = 20; // Error: ‘c’ is private in Parent, cannot be accessed in Child

obj.setValues(); // Setting values inside Child
obj.display(); // Displaying values from Child

return 0;
}

Output:

a: 5, b: 10

Important: Inheritance occurs in both structures (struct) and classes (class) in C++.
  • In a struct, members are public by default.
  • In struct, the default inheritance is public, meaning all public and protected members of the base struct will be accessible in the derived struct.
C++ code Example:

#include <iostream>

struct Parent{
int x; // Public member by default
};

struct Child: Parent{ // Inherits publicly by default
void setX(int value) {
x = value; // Directly setting the inherited 'x'
}
};

int main() {
Child obj;
obj.setX(10); // Setting the value of 'x' in Derived
return 0; // No output, just modifying the value of 'x'
}

2. Inherited (Child) Class as Protected Access Specifier

  • Public members of Parent become protected in the derived class (Child). They are accessible within the derived class (Child) and any classes that further derive from Child.
  • Protected members of Parent stay protected in Child and can only be accessed inside Child or further derived classes.
  • Private members of Parent remain private and are inaccessible in Child.

Derived Class protected- Access Specifiers in Inheritance

Example 1: The derived  class is a protected access specifier

#include <iostream>
using namespace std;class Parent {
public:
int a; // Public member
protected:
int b; // Protected member
private:
int c; // Private member
};

class Child : protected Parent {
// Inherits a, b, c from Parent with protected inheritance
// a (public in Parent) becomes protected in Child
// b (protected in Parent) remains protected in Child
// c (private in Parent) is not accessible in Child
};

int main() {
Child obj;

// obj.a = 5;  Error: ‘a’ is now protected in Child, cannot be accessed outside the class

// obj.b = 10; // Error: ‘b’ is protected in Child, cannot be accessed outside the class
// obj.c = 20; // Error: ‘c’ is private, cannot be accessed outside the class

return 0;
}

Example 2: The derived  class is a protected access specifier – use case

#include <iostream>
using namespace std;

class Parent {
public:
int a; // Public member
protected:
int b; // Protected member
private:
int c; // Private member
};

class Child : protected Parent {
// Inherits a, b, c from Parent with protected inheritance
// a (public in Parent) becomes protected in Child
// b (protected in Parent) remains protected in Child
// c (private in Parent) is not accessible in Child
public:
void setValues() {
a = 5; // OK: ‘a’ is now protected in Child, but accessible inside Child
b = 10; // OK: ‘b’ is protected in Child, so it’s accessible here
// c = 20; // Error: ‘c’ is private in Parent, cannot be accessed in Child
}

void display() {
cout << “a: ” << a << “, b: ” << b << endl;
}
};

int main() {
Child obj;

// obj.a = 5; // Error: ‘a’ is protected in Child, cannot be accessed outside
// obj.b = 10; // Error: ‘b’ is protected in Child, cannot be accessed outside
// obj.c = 20; // Error: ‘c’ is private in Parent, cannot be accessed in Child

obj.setValues(); // Setting values inside Child
obj.display(); // Displaying values from Child

return 0;
}

 

3. Inherited (Child) Class as Public Access Specifier

  • Public members of parent are accessible both within the class (e.g., Child) and from outside the class (e.g., main()).
  • Protected members of parent are accessible within the class (e.g., Child) and derived classes, but not accessible from outside the class.
  • Private members of parent  are not accessible from outside the class, not even in derived classes like Child.

Derived Class public - Access Specifiers in Inheritance

Example 1: The derived  class is a public access specifier

#include <iostream>
using namespace std;
class Parent {
public:
int a; // Public member
protected:
int b; // Protected member
private:
int c; // Private member
};class Child : public Parent {
// Inherits a, b, c from Parent

// a (public member of Parent) is accessible.
// b (protected member of Parent) is accessible.
// c (private member of Parent) is not accessible.

};

int main() {
Child obj;

obj.a = 5; // OK: ‘a’ is public, accessible outside the class

cout << obj.a;
// obj.b = 10; // Error: ‘b’ is protected, cannot be accessed outside the class
// obj.c = 20; // Error: ‘c’ is private, cannot be accessed outside the class
return 0;
}

Output:
5

Summary of Access:

  • In the derived class (Child):

    • a (public member of Parent) is accessible.
    • b (protected member of Parent) is accessible.
    • c (private member of Parent) is not accessible.
  • In the main function (or any function outside Child):

    • a is accessible because it’s public.
    • b is not accessible because it’s protected.
    • c is not accessible because it’s private.

Example 2: The derived  class is a public access specifier – use case

#include <iostream>
using namespace std;

class Parent {
public:
int a; // Public member
protected:
int b; // Protected member
private:
int c; // Private member
};

class Child : public Parent {
// Inherits a, b, c from Parent with public inheritance
// a (public in Parent) remains public in Child
// b (protected in Parent) remains protected in Child
// c (private in Parent) is not accessible in Child
public:
void setValues() {
a = 5; // OK: ‘a’ is public in Parent, so it’s accessible in Child
b = 10; // OK: ‘b’ is protected in Parent, so it’s accessible in Child
// c = 20; // Error: ‘c’ is private in Parent, cannot be accessed in Child
}

void display() {
cout << “a: ” << a << “, b: ” << b << endl;
}
};

int main() {
Child obj;

obj.a = 5; // OK: ‘a’ is public in Child, can be accessed outside
// obj.b = 10; // Error: ‘b’ is protected in Child, cannot be accessed outside
// obj.c = 20; // Error: ‘c’ is private in Parent, cannot be accessed in Child

obj.setValues(); // Setting values inside Child
obj.display(); // Displaying values from Child

return 0;
}

output:

a: 5, b: 10