Access Specifiers in C++

Rishabh Agarwal
4 min readMay 14, 2023

--

Photo by Tim Mossholder on Unsplash

When designing a C++ class, we often want to control who all can access members (both the data members and member functions) of a class. Access specifiers are a way to achieve this. Creators of a class can use access specifier to implement data hiding. Data Hiding helps in separating implementation from interface.

There are two different access specifiers available in C++ :

  • Private — Members marked private are accessible only from class definition. They can be accessed from member functions of the same class.
  • Public — Members marked public are accessible from everywhere. They can be accessed from member functions of the same class, member functions of a different class, or even global functions.

The default access specifier of private is used when no access specifier is mentioned by the user. Also, a class may use different access specifier for different members.

Example to understand Access Specifier

Let us now take an example to understand the effect of access specifiers.

// ComplexV1.cpp

#include <iostream>
#include <cmath>

class Complex {
public:
double re, im;
double getNorm() {
return sqrt(pow(re, 2) + pow(im, 2));
}
};

void print(const Complex& complex) {
// Since re, im are accessible publically
cout << complex.re << " + i" << complex.im << endl;
}

int main() {
Complex complex = {5.1, 3.0}; // Okay
print(complex); // Okay
cout << complex.norm() << endl; // Okay
}

Note that in ComplexV1.cpp all of the data members are marked with public access specifier. Since they are marked public, they can be accessed from any global functions (as evident from their usage in main and print method!).

Let us now see what happens when we make some data members private.

// ComplexV2.cpp

#include <iostream>
#include <cmath>

class Complex {
private:
double re, im;
public:
double getNorm() {
return sqrt(pow(re, 2) + pow(im, 2));
}
};

void print(const Complex& complex) {
// Error
// Since re, im are not accessible publically
cout << complex.re << " + i" << complex.im << endl;
}

int main() {
Complex complex = {5.1, 3.0}; // Error
print(complex); // Error
cout << complex.norm() << endl; // Okay
}

In ComplexV2.cpp, the data members are marked private. This means that they can only be accessed from member functions of the Complex class and nowhere else.

Information Hiding through Access Specifier

Members of a class that are marked private forms its implementation. This is because the class has full ownership to it and can change it anytime without worrying about its usages.

Members that are marked public forms a class’s interface. These members are available for outside world to communicate and make use of your class.

Customarily, we put all attributes in private and member functions in public. This prevents users from taking the state of the class to an undesirable state.

All of this is known as information hiding.

Understanding an object state

State of an object is decided by the values of its data members. Any unique combination of an object’s data members results in a new state for that object.

For some objects, not all values of data members results in a valid state. It is thus important for the respective class to hide the data members and only allow public access to member functions that prevent object’s state from going into an invalid state.

Get-Set Idiom

As mentioned earlier, it is a general practice to make all data members of a class, private. But at the same time you may want users of the class to update or read the value of data members. For this purpose, we create some member functions with the sole purpose of reading and updating the data members.

Member functions that are used to read the value of data members are called get methods. Member functions that are used to update the value of data members are called set methods.

Following is an example of how to use get-set idiom for our Complex class.

class Complex {
private:
double re, im;
public:
double getRe() {
return re;
}
double getIm() {
return im;
}
void setRe(double re) {
this -> re = re;
}
void setIm(double im) {
this -> im = im;
}
};

This brings us to the end of this article. I hope you learnt something new today. If you want to enjoy more short content on C++, do not forget to check out my “in C++” series that contains many more articles on C++ for your byte-sized learning.

Stay tuned for more articles. Till then, continue learning & growing!

--

--

Rishabh Agarwal

Software Developer 2 @ Schrödinger | IIT CSE Graduate - Writes about Software Engineering!