CS 70

Member Variables (a.k.a. Data Members)

Each object of a given class can store its own data. We call that data its data members or member variables (also called instance variables or fields in other object-oriented systems).

In CS 70, our convention is to always name member variables with an ending underscore (_).

  • Duck speaking

    Seems clumsy—why say age_ when you could just say age?

  • LHS Cow speaking

    One reason is that the underscore lets us easily tell the difference between a member variable and a local variable.

  • RHS Cow speaking

    Another is that we often have both. In the code for setAge, you'll see age as a function argument that changes the age_ data member.

  • Hedgehog speaking

    Is a “data member” exactly the same thing as a “member variable”?

  • LHS Cow speaking

    Yes. We'll use the terms interchangeably. Both terms are widely used in the C++ community.

We've highlighted the declarations of the member variables of the Cow class below.

cow.hpp (with some things left out for compactness):

...
class Cow {
 public:
    // We can only have a Cow if we know
    // how many spots it has and how old it is
    Cow(int numSpots, int age);
    Cow() = delete;

    // Moo the right number of times.
    void moo(int numMoos) const;

    // Accessor member functions
    int getNumSpots() const;
    int getAge() const;

    // Mutator member functions
    void setNumSpots(int numSpots);
    void setAge(int age);

 private:
    // Per-Cow data
    int numSpots_;
    int age_;
};
...

Using Member Variables

Inside the body of a member function, you can just use member variables as if they are in scope. They'll refer to the member variables of the object that the member function is called on. (Just like in Java!)

So if we call bessie.getAge(), inside the getAge() member function, any member variables it refers to (e.g., age_) will be the member variables that belong to the bessie object.

  • Duck speaking

    If it's like Java, can I say this.age_ instead?

  • LHS Cow speaking

    No, not quite. It's easier to just say age_. (this works a bit differently in C++ compared to Java, as we'll see later.)

In the code excerpt below, we've highlighted the places in our source file where we use the member variables.

cow.cpp:

...
Cow::Cow(int numSpots, int age)
    : numSpots_{numSpots},
      age_{age}
{
    cout << "Made a cow with " << numSpots_ << " spots!" << endl;
}

void Cow::moo(int numMoos) const {
    for (int i = 0; i < numMoos; ++i) {
        cout << "Moo! ";
    }
    cout << endl;
}

int Cow::getNumSpots() const {
    return numSpots_;
}

int Cow::getAge() const {
    return age_;
}

void Cow::setNumSpots(int numSpots) {
    numSpots_ = numSpots;
}

void Cow::setAge(int age) {
    age_ = age;
}

(When logged in, completion status appears here.)