Accessors (getters) and Mutators (setters)

Accessing data members of a class depends upon the access specifiers of these members. Sometimes there is a necessity to provide access even to private data members. In this case technique of Accessors (getters) and Mutators (setters) are used.

We can use Person class from the previous topic to show how you can access data members with different access types:

class Person
{
public://access control
	string firstName;//these data members
	string lastName;//can be accessed
	tm dateOfBirth;//from anywhere
protected:
	string phoneNumber;//these data members can be accessed inside this class,
	int salary;// by friend functions/classes and derived classes
private:
	string address;//these members can be accessed inside the class
	unsigned long int insuranceNumber;//and by friend classes/functions
};

The access to public data members can be done by using dot operator (arrow operator in the case of pointers):

Person person1;//declare a person
//access public data members
person1.firstName = "Smith";//set first name of person1 to Smith
person1.lastName = "James";//set last name of person1 to James
person1.dateOfBirth.tm_year = 1980;//set  year of birth of person1 to 1980

In the case of pointer of a Person the access to public data members is done in the following way:

Person* person2 = new Person();//declare a person
//access public data members
person2->firstName = "Moore";
person2->lastName = "Daniel";
person2->dateOfBirth.tm_year = 1988;

Data members can also be used as below:

string pName = person1.firstName;
cout << "First name " << pName << endl;

This code produces the following output:

First name Smith

The access to private data members outside of class is allowed only to friend classes or functions. But you can specify a special function Accessor to get the value of private data member. In this case a good style is to start name of this function with get, followed by the data member identifier. The return type must be the same as type of the data member. For example we can create 2 getter functions for address and insuranceNumber data members:

public:
	string getAddress()
	{
		return address;
	}

	long int getInsuranceNumber()
	{
		return insuranceNumber;
	}

 

Now we can use getters to access these private data members:

cout << "Person1 address: " << person1.getAddress();

Accessors are often used to perform some additional checks before returning a value. For example, we can check if the address is not an empty string before returning address value. This can avoid some of the errors in runtime:

string getAddress()
{
	if (!address.empty())
		return address;
	else
		return "Attention!!! Address is empty";
}

As you can see, string is a class too. We are calling its public member function empty () to determine if a string is empty.

Mutators (setters) are used to set values of private data members. One of the main goals of a mutator is to check correctness of the value to be set to data member. A setter’s name starts with set, followed by name of data member. Setter must have one parameter of the same type as the data member to bet set by the setter. Here is an example of creating setter for insurance number: we can check if a 9 digits number is passed to the setter and display an error message in the case is a wrong number:

public:
	void setInsuranceNumber(unsigned long int insurance)
	{
		if (insurance >= 100000000 && insurance <= 999999999)
			insuranceNumber = insurance;//a correct value is set
		else
			//display only error message and do not set incorrect value
			cout << "Incorect Insurance number" << endl;
}

Sometimes you can use the return value of the setter to keep track if a value is set. We can modify the above example to work in the following way: the setter will return true if the correct value is set. Otherwise it will return false:

bool setInsuranceNumber(unsigned long int insurance)
{
	if (insurance >= 100000000 && insurance <= 999999999)
	{
		insuranceNumber = insurance;//a correct value is set
		return true;//everything is ok
	}
	else
		//do not set incorrect value and return false
		return false;
}

It can be used in the program to get a correct input from user:

unsigned long int iNum;
cout << "Please, enter you Insurance Number:" << endl;
cin >> iNum;
//try to set the value
bool result = person1.setInsuranceNumber(iNum);
while (!result)//while result is not true
{
	cout << "Enter a valid Insurance Number:" << endl;
	cin >> iNum;
	//try to set the value again
	result = person1.setInsuranceNumber(iNum);
}

You can try to enter an incorrect value:

Please, enter you Insurance Number:

1234

Enter a valid Insurance Number:

032

Enter a valid Insurance Number:

123456789

Protected data members can be accessed in the same way as public data members from friend functions or classes and from derived classes. If you need to provide access to protected data members from any other functions, you will have to use the same technique as for accessing private data members.

Translate »