CS 70

Member Functions

As with other functions we've seen, member functions need to be declared (in the header file) and defined (in the source file).

Declaring Member Functions

The declarations for the member functions of the Cow class are highlighted in cow.hpp below.

cow.hpp:

...
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_;
};
...
  • Duck speaking

    Why are some member functions marked const? I only know about marking variables as const. And why at the end of the line, that's so weird!

  • LHS Cow speaking

    Good question! Let's put a pin in that for now. We can talk about it next.

  • Hedgehog speaking

    Put a pin in it? Leave it to me!

  • LHS Cow speaking

    Uh… thanks, Hedgehog. Teamwork makes the dream work!

Defining Member Functions

Member functions are defined in the source file. The definitions are highlighted in cow.cpp below.

cow.cpp:

...
using namespace std;

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;
}
  • Horse speaking

    Hay, why do they look different in the header file and in the source file? They all say Cow::

  • Duck speaking

    And what are those :: things?

  • LHS Cow speaking

    Ah yes. We use :: so the compiler knows we are defining a function inside our class.

If we had just written void moo(int numMoos) {... then we would be defining a function named moo, but that function would have no clear relationship with the class. Also, there might be multiple classes that have moo functions!

The :: is called the scope-resolution operator. Essentially someplace::something means “something inside of someplace”.

One way to see a class is as a collection of variables and functions. The scope-resolution operator lets us specify which “collection” to look in.

So Cow::moo means “the moo function/variable inside of Cow”.

We don't need to specify the scope in the class definition in cow.hpp because the member-function declarations are clearly within the class (they are between the curly braces!) We also don't need it inside the functions themselves (not even inside their parameter lists).

  • Duck speaking

    Having to say Cow:: over and over seems silly and repetitive. Our file cow.cpp only has definitions for member functions in the Cow class!

  • LHS Cow speaking

    C++ doesn't require us to put all the member functions from one class in a single file. We could have one function per file, or put, say, Cow::getAge(), Pig::getAge(), and Goat::getAge() all in a single age.cpp file. So having to use the Cow:: prefix to refer to member functions in the Cow class is a consequence of C++ giving programmers more flexibility.

Say we have a class Temperature that has a member function declared as

float convertCtoF(float celcius);

What would the function header in the definition of this function be?

Remember that a “function header” is the first line of a function definition, which includes the return type, the full function name, and its parameter list. Don't include the opening curly brace { in your answer.

Calling Member Functions

To call a member function, you need to have an instance of a class (i.e., an object) to call it on.

You use the familiar dot notation to access members of an object.

You can see some examples highlighted in main.cpp below, where we have instances of the Cow class.

main.cpp:

...
using namespace std;

int main() {
    Cow bessie{3, 12};
    const Cow mabel{1, 2};

    // This line wouldn't work!
    // Cow duke;

    bessie.moo(1);
    mabel.moo(2);
    bessie.setAge(4);

    // This line wouldn't work!
    // mabel.setAge(2);

    return 0;
}

(When logged in, completion status appears here.)