The word access means to read or change the value of a variable, and it also means to use a function. C++ access specifiers are the words, “private,” “protected,” and “public.” They decide whether a member can access other members of its class, or if a function or operator outside the class and not belonging to the class can access any member of the class. They also decide whether a member of a derived (child) class can access a member of a parent class.
Basic knowledge of C++ is required to understand this article and to test the code provided.
Article Content
- The Public and Private Specifiers
- The Protected Specifier
- Derived Class Specifiers and Member Specifiers
- Conclusion
The Public and Private Specifiers
Class
Any member of a class can access any other member of that same class, independent of which is labeled “public” or “private.” Consider the following program:
using namespace std;
class TheCla
{
private:
int num1;
int num2;
public:
TheCla(int n1, int n2)
{
num1 = n1; num2 = n2;
}
int method()
{
return num1;
}
};
int main()
{
TheCla obj(10, 20);
int no2 = obj.method();
cout<<no2<<'\n';
//int no1 = obj.num1;
return 0;
}
The output is 10. The private members are num1 and num2. The public members are TheCla() and method(). Note that TheCla() is the constructor function that initializes variables of interest. The region of an access specifier begins from its label to the end of the class description (definition) or to the start of another access specifier.
In the main() function, the first statement is the instantiation involving the constructor function, which initializes num1 and num2. The next statement calls the public member, method(), of the class.
Now, in the class description (definition), the public member function, TheCla(), accesses the private members, num1 and num2. Also, the public member function, method(), accesses the private member, num1. Any member within a class description can access any other member within the same class description; it does not matter which member is private or public.
However, a function or operator not declared in the class description and outside the class description can access only public members of the class. The main() function, for example, is a function declared outside the class description. It has been able to access only the method() and the TheCla() public members. Inside the main() function, the TheCla() function is obj(10, 20).
An outside function or outside operator, such as the main() function, cannot access any of the private members of the class, such as num1 or num2. Remove the comment indicator, //, from the last-but-one statement in main(). If you attempt to compile the program, note that the program will not compile, giving an error message.
Default Specifier
The default specifier for a class is “private.” So, the above class description is the same as the following description, private, but without the specifier:
{
int num1;
int num2;
public:
TheCla(int n1, int n2)
{
num1 = n1; num2 = n2;
}
int method()
{
return num1;
}
};
Note: the access specifier label begins with the specifier, and is then followed by a colon.
The Protected Specifier
Within a class description, and from an outside function or outside operator, the protected specifier is the same as the private specifier. Now, replace the private specifier in the above program with the specifier, protect, and remove the comment indicator, //, from the last-but-one statement in the main() function. If you attempt to compile the program, note that the program will not compile, giving an error message.
The issue of the protected specifier comes up when members of the derived (inherited) class must access members of the base (parent) class.
Public Derived Class with Public Members
Consider the following program:
using namespace std;
class TheCla
{
public:
int num1 = 10;
protected:
int num2 = 20;
private:
int num3 = 30;
};
class ChildCla : public TheCla
{
public:
int method1()
{
return num1;
}
int method2()
{
return num2;
}
/*int method3()
{
return num3;
} */
};
int main()
{
ChildCla childObj;
int no1 = childObj.method1();
cout<<no1<<'\n';
int no2 = childObj.method2();
cout<<no2<<'\n';
return 0;
}
The output is:
10
20
In the base class, num1 is public, num2 is protected, and num3 is private. In the derived class, all the member functions are public. The first function, method1(), accesses the public data member, num1. The second function, method2(), accesses the protected data member, num2. The third function, method3(), though currently commented out, should access the private data member, num3.
A derived class is not declared without an access specifier (public, protected, or private). Above, the derived class is declared with the public specifier, that is:
Now un-comment the third member function definition in the derived class. If you attempt to compile the program, note that it will not compile, giving an error message.
Note: When the whole derived class is declared public, its members cannot access the private members of the base class. Its members can, however, access the public and protected members of the base class. The above program illustrates this.
However, note that a public member of the public derived class can access a protected member of the base class.
Derived Class Specifiers and Member Specifiers
Protected Derived Class with Public Members
Replace the “public” specifier with “protected” in the declaration of the derived class above, as follows:
Compile and run the program and note that the result is the same as before.
So, when the whole derived class is declared protected, its members cannot access the private members of the base class. Its members can, however, access the public and protected members of the base class. This is the same as when the derived class is declared public.
Note: a protected member of the public derived class can access a protected member of the base class.
Private Derived Class with Public Members
Replace the “protected” specifier with “private” in the declaration of the derived class above, as follows:
Compile and run the program and note that the result is the same as before.
So, when the whole derived class is declared private, its members cannot access the private members of the base class. Its members can, however, access the public and protected members of the base class. This is the same as when the derived class is declared protected or public.
Public Derived Class with Protected Members
Type, compile, and run the following program, in which the whole derived class is protected, and its members are also protected. Some code segments are as follows:
using namespace std;
class TheCla
{
public:
int num1 = 10;
protected:
int num2 = 20;
private:
int num3 = 30;
};
class ChildCla : public TheCla
{
protected:
int method1()
{
return num1;
}
int method2()
{
return num2;
}
/*int method3()
{
return num3;
} */
};
int main()
{
/*ChildCla childObj;
int no1 = childObj.method1();
cout<<no1<<'\n';*/
/*int no2 = childObj.method2();
cout<<no2<<'\n'; */
return 0;
}
The program works as it is. There is no output, and there is not supposed to be any output, based on how the program has been typed.
Now, un-comment the function definition, method3(), in the derived class. If you attempt to compile the program, note that it will not compile, giving an error message. This means that a private member cannot be accessed from an outside function, outside operator, or derived class. This is the same conclusion as was concluded above, concerning access to a private member.
Note: a protected member of the protected derived class can access a protected member of the base class.
Now, put the comments back in the derived class and un-comment the first code segment in the main() function. If you attempt to compile the program, note that the program will not compile because of the first code segment in the main() function. This effect is not new. Apart from the derived class, outside functions, and outside operators, the protected and private members of a (base or derived) class are of the same specifier, private. The main() function sees the protected member of any class, whether base or derived, as of the same specifier, private, and is forbidden from accessing it.
If the second code segment of the main() function is un-commented, the same explanation will apply. That is, the main() function will not be able to access a protected or private member of the derived class or of the base class. This is independent of whether a protected member of the derived class could access a protected member of the base class.
Protected Derived Class with Protected Members
Replace the “public” specifier with “protected” in the declaration of the derived class above, as follows:
Put the comment of the code segments back into the main() function, if this has not already been done. Compile and run the program and note that the result is as before.
Private Derived Class with Protected Members
Replace the “protected” specifier with “private” in the declaration of the derived class above, as follows:
Compile and run the program and note that the result will be as before.
Public Derived Class with Private Members
Replace the “private” specifier with “public” in the declaration of the derived class above, as follows:
Make the members of the derived class private. Compile and run the program. The result is not different from the “Public Derived Class with Protected Members” case.
Protected Derived Class with Private Members
Replace the “public” specifier with “protected” in the declaration of the derived class above, as follows:
Compile and run the program. This result is no different from the “Protected Derived Class with Protected Members” case.
Private Derived Class with Private Members
Replace the “protected” specifier with “private” in the declaration of the derived class above, as follows:
Compile and run the program. This result is no different from the “Private Derived Class with Protected Members” case.
Conclusion
C++ access specifiers are the words “private,” “protected,” and “public.” They decide access for members of a class. The region of an access specifier begins from its label, to the end of the class description (definition), or to the start of another access specifier. Any member of a class can access any other member of that same class. A private member of a class cannot be accessed by any outside function, any outside operator, or a derived class.
The member of the base class must be made protected so that a private member of the base class can be accessed by a member of the derived class. This protected member of the base class is seen as a private member of the base class by an outside function or an outside operator.
A public member of a class can be accessed by any outside function, any outside operator, or a derived class.
In the absence of any access specifier in a class, the private specifier is assumed. That is, the default access specifier is private.
References Used in This Work
- Alireza Ebrahimi, INHERITANCE: REUSABILITY AND EXTENDABILITY
- S. Malik, Data Structures Using C++ 2nd Edition