Occasionally you may see a C++ program that declares member functions that act like public data members. Such functions return references to private data members. For example:
// BAD TECHNIQUE: Member function that returns a reference
class Date
{
public:
Date( int mn, int dy, int yr ); // Constructor
int &month(); // Set/get month
~Date(); // Destructor
private:
int month_member, // (_member appended to
day_member, // distinguish names from
year_member; // member functions)
};
int &Date::month()
{
month_member = max( 1, month_member );
month_member = min( month_member, 12 );
return month_member;
}
// ...
The month member function returns a reference to the data member. This means that the function call expression month() can be treated as an alias for the private data member. For example:
// BAD TECHNIQUE: using member function that returns a reference
void main()
{
int i;
Date deadline( 3, 10, 1980 );
i = deadline.month(); // Read month value
deadline.month() = 4; // Modify month value
deadline.month()++; // Increment
}
The member function behaves just like a data member. Consequently, the function call deadline.month() can appear on the left side of an assignment, in the same way that deadline.month_member could if the data member were public. You can even increment its value with the ++ operator.
You can assign an illegal value to month_member this way, but the month function performs range-checking to correct any such illegal values the next time it is called. As long as all of Date's other member functions don't access the data member directly, but always use that function instead, the Date class functions correctly.
You should not use this technique for a variety of reasons. First, the syntax can be very confusing to people reading your program. Second, range checking is performed every time a data member is read, which is inefficient. Finally, and most importantly, this technique essentially makes the data member public. With this design, you cannot change the implementation of a private data member without rewriting all the programs that use the class. If you wanted to encode the month and day values within a single integer, you would have to change the member functions and rewrite all the programs that used Date.
To retain the benefits that member functions offer, you should always give your classes separate member functions to read and modify private data members.