By definition, an accessor of a class is a member function which accesses, and perhaps returns, the member variables of an instance of the class (of an object), however, it does not change any of the member variables.
Within a class member declaration, the declaration of an accessor member function is done by declaring the function, but also by adding the const modifier to the right of the declaration.
For example, the following code demonstrates an accessor member function
#include <iostream> using namespace std; class Box { private: int value; public: Box( int ); // Accessors int getValue() const; // Mutator (non-accessor) void setValue( int ); }; Box::Box( int v ):value( v ) { // empty constructor } int Box::getValue() const { return value; } void Box::setValue( int v ) { value = v; } int main() { Box b( 42 ); cout << "The box b contains " << b.getValue() << endl; return 0; }
If you attempt to assign to value inside the member function int getValue(), you will get a compile-time error.
Both the member function declaration and the member function definition must have the const modifier, otherwise the compiler will not associate the two and return an error:
main.cpp:22: error: prototype for `int Box::getValue()' does not match any in class `Box' main.cpp:12: error: candidate is: int Box::getValue() const
Note that the error message does give some indication as to what is wrong.
If you were to replace the definition of the accessor int getValue() const with
int Box::getValue() const { value = 0; return value; }
which assigns to the member variable value, you get the following error:
main.cpp: In member function `int Box::getValue() const': main.cpp:23: error: assignment of data-member `Box::value' in read-only structure
The term read-only says that the member function can read, but cannot be assigned (written to).
Another restriction on accessors is that they can only call other accessors which have explicitly declared to be constant. This is only logical, as it would be non-sensical to call a member function which could modify the member variables.
For example, if you modify the accessor int getValue() const as follows, calling the mutator void setValue( int ):
int Box::getValue() const { setValue( 667 ); return value; }
then you would get the compile-time error
x.cpp: In member function `int Box::getValue() const': x.cpp:23: error: passing `const Box' as `this' argument of `void Box::setValue(int)' discards qualifiers
What this says is that by calling void Box::setValue(int) on this, you are loosing the qualifier. This error will appear whether or not the mutator actually changes the value.
Explicitly declaring accessors is very reasonable from a software engineering point-of-view. If the design of a function says that a particular member function should not actually change the object on which it is called, then it would be useful to have some means of verifying this at compile time. Thus, mistakes can be avoided.