In the previous section, we saw how to provide access to private member variables through a public member functions. That is a common pattern: for any variable we want to provide access to, we provide getter function. A getter or accessor is a function that just returns the value of a member variable.
If we want to provide the ability for outside code to modify a member variable, we can add a setter function. These are functions that take a value and use that to set a member variable. This version of the Point class adds a setter for m_x:
When main calls p1.setX(5.0), it passes in the value 5. The Point::setX(double x) function takes that parameter and assigns the value into the m_x member variable of p1.
As with getters, setters provide a limited way for outside code to manipulate the object. Outside code canβt directly change m_x, it has to use the interface to ask a given point to please make the change to itself. This means the class can βprotect itselfβ from unsafe or unwanted changes.
Say you are creating a Person class and you want to make sure that the age of a person never gets set to a negative value. You could design the class to prevent that from happening:
When main tries to set a negative age, the Person class ignores that request and prints an error message. (In a real program we might throw an exception.)
The person programming Person is the expert who knows all the important ins and outs of the Person class. They know that a negative value is going to cause problems later. The person programming main does not realize that issue even exists. If they could set `p1.m_age = -5;` directly, they could end up causing the program to do something horrible later on.
By forcing others to use the public interface and then preventing unwanted modifications in that interface, the programmer of the Point class is able to limit the potential for such issues.
This structure also gives the programmer of the Person class the freedom to change how age is stored internally without breaking outside code. Maybe in the future we change the class to store the birthdate instead of the age. As long as we keep the same public interface with getAge() and setAge(int age), outside code will not be affected by that change.
Setters are a special kind of mutator function. A mutator is any function that changes the state of an object. While a setter sets a member to a particular value, another kind of mutator might set more than one value or change a variable in a way that doesnβt allow outside code to set a particular value.
When looking at a simple code example or writing a small program where you are responsible for all of the code, much of what we do in object-oriented programming may seem unnecessary. Keep in mind that is not what OOP was designed for. In a large project, especially one with many programmers, the layers of abstraction and information hiding can be very valuable.
In main we want to create a Circle, set the radius to 2.4 and output the radius. Then change the radius to 3.6 and output the new radius. We want to use the public interface of the Circle class and not depend on the private details of the class.