Lesson 4
Access Specifiers in Inheritance
Lesson Introduction

Welcome to our lesson on "Access Specifiers in Inheritance" in C++! Access specifiers (public, protected, and private) are key in object-oriented programming as they help control access to class members. This lesson will focus on understanding how these access specifiers work in inheritance.

By the end of this lesson, you'll know how access specifiers affect the accessibility of inherited class members.

Access Specifiers Overview

In C++, access specifiers set the accessibility of class members (attributes and methods). The primary access specifiers are:

  • public: Members are accessible from outside the class.
  • protected: Members are accessible within the class and by derived class instances.
  • private: Members are accessible only within the class declaring them.

These controls help ensure data encapsulation and security by preventing unauthorized access. We have already seen public and private specifiers in the previous course. Let's discuss the protected in deeper details.

The Protected Specifier in Detail

The protected specifier in C++ allows members to be accessible within the same class, as well as any derived classes. However, these members are not accessible from code that is outside the class hierarchy.

Let's consider the following example to understand the protected specifier more clearly:

C++
1#include <iostream> 2 3class Parent { 4 protected: 5 int protectedVar; 6 public: 7 Parent() : protectedVar(0) {} 8 void setProtectedVar(int val) { 9 protectedVar = val; 10 } 11}; 12 13class Child : public Parent { 14 public: 15 void display() { 16 std::cout << "protectedVar: " << protectedVar << std::endl; // OK: Accessible within derived class 17 } 18}; 19 20int main() { 21 Child obj; 22 // obj.protectedVar = 10; // Error: protectedVar is not accessible outside the class hierarchy 23 obj.setProtectedVar(10); // OK: Access through public member function of the base class 24 obj.display(); // Output: protectedVar: 10 25 return 0; 26}

In this example:

  • protectedVar is declared as protected in the Parent class.
  • The Child class, which is derived from Parent, can access protectedVar directly within its member functions.
  • From main(), direct access to protectedVar is not allowed, ensuring that it remains encapsulated within the class hierarchy.

Advantages of Using Protected:

  1. Encapsulation with Controlled Exposure: While private members totally encapsulate data, protected members allow derived classes to reuse and extend functionality.
  2. Inheritance Flexibility: Derived classes can build upon the base class without exposing sensitive data to the outside world.
Public Inheritance Explained

As you might recall, the syntax of the inheritance is the following:

C++
1class Derived : public Base

Here, we specify the inheritance access specifier, which defines what happens to the class fields' specifiers in the derived class. So far, we only used the public inheritance access specifier.

When a class inherits from another class publicly, the access specifiers of the base class members are preserved in the derived class.

C++
1#include <iostream> 2 3class Base { 4 public: 5 int publicVar; 6 protected: 7 int protectedVar; 8 private: 9 int privateVar; 10}; 11 12class Derived : public Base { 13 public: 14 void display() { 15 publicVar = 1; // OK: public in Base remains public in Derived 16 protectedVar = 2; // OK: protected in Base remains protected in Derived 17 // privateVar = 3; // Error: private in Base is not accessible in Derived 18 std::cout << "publicVar: " << publicVar << " protectedVar: " << protectedVar << std::endl; 19 } 20}; 21 22int main() { 23 Derived obj; 24 obj.display(); // Output: publicVar: 1 protectedVar: 2 25 return 0; 26}

Here:

  • publicVar: Accessible in Derived because it stays public.
  • protectedVar: Accessible through member functions because it remains protected.
  • privateVar: Inaccessible in Derived because it is private in Base.
Protected Inheritance Explained

In protected inheritance, public and protected members of the base class become protected in the derived class.

C++
1#include <iostream> 2 3class Base { 4 public: 5 int publicVar; 6 protected: 7 int protectedVar; 8 private: 9 int privateVar; 10}; 11 12class Derived : protected Base { 13 public: 14 void display() { 15 publicVar = 1; // OK: public in Base becomes protected in Derived 16 protectedVar = 2; // OK: protected in Base remains protected in Derived 17 // privateVar = 3; // Error: private in Base is not accessible in Derived 18 std::cout << "publicVar: " << publicVar << " protectedVar: " << protectedVar << std::endl; 19 } 20}; 21 22int main() { 23 Derived obj; 24 // obj.publicVar = 1; // Error: publicVar is now protected in Derived 25 obj.display(); // Output: publicVar: 1 protectedVar: 2 26 return 0; 27}

Here:

  • publicVar: Becomes protected, not accessible directly from main.
  • protectedVar: Remains protected, accessible within Derived.
  • privateVar: Inaccessible in Derived.
Private Inheritance Explained

In private inheritance, public and protected members of the base class become private in the derived class.

C++
1#include <iostream> 2 3class Base { 4 public: 5 int publicVar; 6 protected: 7 int protectedVar; 8 private: 9 int privateVar; 10}; 11 12class Derived : private Base { 13 public: 14 void display() { 15 publicVar = 1; // OK: public in Base becomes private in Derived 16 protectedVar = 2; // OK: protected in Base becomes private in Derived 17 // privateVar = 3; // Error: private in Base is not accessible in Derived 18 std::cout << "publicVar: " << publicVar << " protectedVar: " << protectedVar << std::endl; 19 } 20}; 21 22int main() { 23 Derived obj; 24 // obj.publicVar = 1; // Error: publicVar is now private in Derived 25 obj.display(); // Output: publicVar: 1 protectedVar: 2 26 return 0; 27}

Here:

  • publicVar: Becomes private in Derived, not accessible directly from main.
  • protectedVar: Becomes private in Derived, not accessible from main.
  • privateVar: Inaccessible in Derived.
Lesson Summary

Awesome job! You’ve learned how access specifiers control member accessibility in inheritance. To recap:

  • Public Inheritance: Public members stay public; protected members stay protected.
  • Protected Inheritance: Public and protected members become protected.
  • Private Inheritance: Public and protected members become private.

These concepts help secure and organize your C++ programs.

Now, it's time for some hands-on practice! You'll use CodeSignal to apply access specifiers in inheritance, which will solidify your understanding. Have fun and good luck!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.