In depth understanding of the use of public protected and private in C++

  • 2020-04-02 02:40:09
  • OfStack

Those of you who are new to C++ will often see public, protected, and private in your classes and the scope of access they represent in your inheritance. Today, I'm going to take a look at the use of public, protected, and private in C++. I believe it will be of great help for you to master C++ programming.

The first thing we need to understand here is the following.

1. One of the characteristics of class is encapsulation, and the function of public and private is to achieve this purpose. So:

User code (outside the class) can access public members but not private members; Private members can only be accessed by class members (within the class) and friends.

2. Another feature of a class is inheritance, and protected serves this purpose. So:

Protected members can be accessed by derived class objects and not by user code (outside the class).

Here's an example:


#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
  int a;
  A(){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a = 4;
  }
  void fun(){
    cout << a << endl;    //correct
    cout << a1 << endl;   //correct
    cout << a2 << endl;   //correct , access within the class 
    cout << a3 << endl;   //correct , access within the class 
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};
int main(){
  A itema;
  itema.a = 10;    //correct
  itema.a1 = 20;    //correct
  itema.a2 = 30;    //Error. Protected members cannot be accessed outside the class
  itema.a3 = 40;    //Error, private member cannot be accessed outside the class
  system("pause");
  return 0;
}

Characteristics in inheritance:

Remember: inheritance or no inheritance, the above rules always apply!

There are three ways of inheritance: public, protected and private, which change the access properties of the members of the base class accordingly.

1. Public inheritance: The access properties of the base classes public, protected, and private become public, protected, and private

2. Protected inheritance: The access properties of the base classes public, protected, and private are changed to: protected, protected, and private

3. The private inheritance: The access properties of the base classes public, protected, and private become: private, private, and private, respectively, in the derived classes

But in either case, neither of the above two points has changed:

1. Private members can only be accessed by members of this class (within the class) and friends, and cannot be accessed by derived classes;

2. Protected members can be accessed by derived classes.

Take a look at the following code:

1. Public inheritance

The code is as follows:


#include<iostream>
#include<assert.h>
using namespace std;

class A{
public:
  int a;
  A(){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a = 4;
  }
  void fun(){
    cout << a << endl;    //correct
    cout << a1 << endl;   //correct
    cout << a2 << endl;   //correct
    cout << a3 << endl;   //correct
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};
class B : public A{
public:
  int a;
  B(int i){
    A();
    a = i;
  }
  void fun(){
    cout << a << endl;       //correct . public Members of the 
    cout << a1 << endl;       //correct The base class public Member, still in a derived class public Members. 
    cout << a2 << endl;       //correct The base class protected Member, still in a derived class protected Can be accessed by derived classes. 
    cout << a3 << endl;       //Error, the private member of the base class cannot be accessed by the derived class.
  }
};
int main(){
  B b(10);
  cout << b.a << endl;
  cout << b.a1 << endl;   //correct
  cout << b.a2 << endl;   //Error. Protected members cannot be accessed outside the class
  cout << b.a3 << endl;   //Error, private member cannot be accessed outside the class
  system("pause");
  return 0;
}

2. Protected inheritance:

The code is as follows:


#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
  int a;
  A(){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a = 4;
  }
  void fun(){
    cout << a << endl;    //correct
    cout << a1 << endl;   //correct
    cout << a2 << endl;   //correct
    cout << a3 << endl;   //correct
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};
class B : protected A{
public:
  int a;
  B(int i){
    A();
    a = i;
  }
  void fun(){
    cout << a << endl;       //correct . public Members. 
    cout << a1 << endl;       //correct The base class public Member becomes in a derived class protected , can be accessed by derived classes. 
    cout << a2 << endl;       //correct The base class protected Member in a derived class or protected , can be accessed by derived classes. 
    cout << a3 << endl;       //Error, the private member of the base class cannot be accessed by the derived class.
  }
};
int main(){
  B b(10);
  cout << b.a << endl;       //correct . public Members of the 
  cout << b.a1 << endl;      //Error. Protected members cannot be accessed outside the class.
  cout << b.a2 << endl;      //Error. Protected members cannot be accessed outside the class.
  cout << b.a3 << endl;      //Error, private member cannot be accessed outside the class.
  system("pause");
  return 0;
}

3. The private inheritance:

The code is as follows:


#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
  int a;
  A(){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a = 4;
  }
  void fun(){
    cout << a << endl;    //correct
    cout << a1 << endl;   //correct
    cout << a2 << endl;   //correct
    cout << a3 << endl;   //correct
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};
class B : private A{
public:
  int a;
  B(int i){
    A();
    a = i;
  }
  void fun(){
    cout << a << endl;       //correct . public Members. 
    cout << a1 << endl;       //correct The base class public Members of the , Becomes in a derived class private, Can be accessed by derived classes. 
    cout << a2 << endl;       //correct The base class protected Member becomes in a derived class private, Can be accessed by derived classes. 
    cout << a3 << endl;       //Error, the private member of the base class cannot be accessed by the derived class.
  }
};
int main(){
  B b(10);
  cout << b.a << endl;       //correct . public Members of the 
  cout << b.a1 << endl;      //Error, private member cannot be accessed outside the class.
  cout << b.a2 << endl;      //Error, private member cannot be accessed outside the class.
  cout << b.a3 << endl;      //Error, private member cannot be accessed outside the class.
  system("pause");
  return 0;
}

The above code is fully commented and should be understandable to the reader. If you look closely at the derived class B in the code that defines a member a with the same name as the base class, the base class a still exists and can be verified.


int main(){
  cout << sizeof(A) << endl;
  cout << sizeof(B) << endl;

  system("pause");
  return 0;
}

Output:

16

20

So the derived class contains all the members of the base class as well as the new members. The members with the same name are hidden and only members of the derived class are called when called.

If you want to call a member of the base class with the same name, you can use the following method:


int main(){

  B b(10);
  cout << b.a << endl;
  cout << b.A::a << endl;

  system("pause");
  return 0;
}

Output:

10

4

Remember we're accessing it outside of the class, and a is public in the base class, so we should inherit it public so that a is still public in the derived class and accessible outside of the class.

Interested readers can debug and run an example of this article to deepen their impression and gain something new.


Related articles: