Skip to main content

Section 16.5 Member Functions

If we make the member variables of a class private, they are part of its implementation and outside code cannot access them directly. So how can outside code get or set the values of those member variables?
To allow for that, we need to provide an interface through which outside code can access those member variables. We do this by declaring member functions (also sometimes called methods) that are part of the class and have access to the private member variables. We then make those functions public so that outside code can call them.
Listing 16.5.1.
class Point {
// Interface
// public member functions
public:
    double getX() {
        return m_x;
    }

// Implementation
// private member variables
private:
    double m_x;
    double m_y;
}
Note that the function getX is in a public block. Then look closely at the code inside the function getX(). What looks odd?
There is no declaration of m_x in this function! It is not declared as a parameter, nor is it declared as a local variable. It is the member variable of Point named m_x. getX is a part of a Point object, and every object has a m_x, so it is assumed that m_x refers to the member variable of β€œthe current object”.

Insight 16.5.1.

Inside member functions, we always have access to the member variables of the object, even if they are private.
To call a member function, we always need to call it on a particular object:
p1.getX();
p2.getX();
Trying to use a member function without an object is a syntax error. There is no getX() function, there is only the getX() function that is a member of the Point class. (Point::getX() is the full name of this function - β€œthe getX that is a part of Point”.)
The fact that we call the function on a particular Point is what allows the function to know which object’s m_x to return.
Run this Codelens sample. You can ignore the code on lines 8-11 for now. But pay special attention each time it enters the getX function. When it does so, you will see a stack frame for Point::getX() and in that stack frame, you will see a variable called this that points at the object that is running the code. During the first call to Point::getX(), it will point to p1 since we called p1.getX() on line 23. Then, on line 26 when we call p2.getX(), this will be pointing at p2.
Listing 16.5.2.
A hand drawn memory diagram might look like this:
When getX is called on p1, this refers to p1
Figure 16.5.3. A memory diagram of p1 executing getX

Note 16.5.2.

We will learn more about exactly what this is in SectionΒ 18.9. For now, you can think of it as an alias for β€œthe object running the code”. When we say m_x in a member function, it is understood to mean this->m_x or β€œthe m_x variable of the object running this code”.
The code in main is not allowed to directly access the private member variable m_x of the Point. But it can politely ask the Point to give it the value by calling a public member function getX(). The getX() function, as a member of the class, has access to the private information. Thus, we are providing an interface (public functions) so outside code can interact with the implementation (private variables) in a controlled way.

Insight 16.5.3.

A good rule of thumb is: member variables should be private and member functions public.
There will be rare exceptions:
  • A constant variable might reasonably be made public - there is no way for outside code to use it to change the state of the object.
  • There might be a function that is a useful helper to other member functions but makes no sense for outside code to use. That function could be marked private to prevent its use from outside the class.
But unless you have a very good reason, stick the the rule of thumb.
Currently, the interface does not allow outside code to change the m_x variable. From main, we can call getX() but there is no public member function that allows us to change it.

Checkpoint 16.5.1.

Which of the following appear to be accessor functions based on their name?
  • getSuit
  • setRank
  • print
  • getRank

Checkpoint 16.5.2.

Examine this code. Then decide what best describes the meaning of m_red on line 6.
class Color {
private:
    int m_red, m_green, m_blue;
public:
    int getRed() {
        return m_red;
    }
};

int main() {
    Color c1;
    Color c2;
    c1.getRed();
}
  • The m_red value of whatever Color object getRed() was called on
  • The m_red value of c1.
  • Although we only currently use getRed on c1, it is possible that we could later call it on c2. So m_red is not guaranteed to be the value of c1.
  • The m_red value of c2.
  • We are not using c2.
  • The m_red value of the Color class.
  • The class itself does not have a m_red value. The class is just a blueprint for creating objects. The m_red variable is a member of each instance of the class.
You have attempted of activities on this page.