Strong encapsulation requires that classes hide attributes (i.e., member variables) from client programs; classes hide their member variables s by making them private
. However, there are times when a client has a legitimate need to know some things about an object. For example, if the client program is using a Person object, at some time, it may need to know the name of the represented person. Similarly, objects often must change over time to reflect the problem domain's ever-changing conditions. For example, a person may move, and the program must update the person's address. We could satisfy that legitimate need by making the data public but doing so would expose the data to both legitimate and illegitimate use. Fortunately, there is a way to satisfy the legitimate need to access private data while maintaining encapsulation and, more importantly, maintaining the security offered by the private
specification.
The preferred way of allowing one object (the client) to access the private data of another object (the server or supplier) is to define access functions in the server object. Access functions, which become a part of the object's public interface, provide controlled access to some of an object's private data. Two kinds of access functions exist: accessor or getter and mutator or setter.
Accessor or getter functions allow clients to get the value saved in one of a supplier object's member variables. Getter functions are typically relatively small and simple, but the following example illustrates that they can be more complex when necessary. By default, C++ functions perform a return by value (i.e., return by copy), so a client can get the value saved in an object but cannot change the value. However, if a getter function returns a pointer or a reference, the client can change a saved value. To prevent clients from changing an object, getter functions can return const
pointers and references (covered in detail later in the chapter). C++ follows a similar but less strict naming convention than Java for naming getter functions. Like Java programmers, C++ programmers often use camel notation (aka camel case) to name class features. However, the C++ naming style is less strict, so another standard naming style adds the prefix "get" to the variable name. For example, suppose that a class has a string member variable, string name;, then common getter function names are:
string getName()
C++ and Javastring get_name()
C++Mutator/setter functions allow clients to change the value stored in one of an object's member variables. Setter functions may include validity checks or reformat data to match a standard format. The naming conventions are similar to those for accessor functions. Assuming the same string name;
member variable as before, then common setter function names are:
void setName(string n)
C++ and Javavoid set_name(string n)
C++class Person { private: string name; int age; public: string getName() // accessor or getter function { return name; } void setAge(int a_age) // mutator or setter function { if (age > 0 && age < 115) age = a_age; } };
getName
and a mutator or setter function named setAge
. The setter function performs some simple validity checks.
At first, it may seem like accessors and mutators (or getters and setters) violate encapsulation, but they do offer many advantages over simply setting the attribute visibility to public
:
![]() |
![]() |
(a) | (b) |
int size() { return sp; }
int size()
, remains constant, we are free to replace return sp;
with the counting code. Setters and getters help class designers create a stable public interface even when the class's underlying implementation changes.