CS 70

Before You Start

Can two different classes both define member functions with the same name? (This is not a trick question!)

They can, and you've already seen examples of these, such as

  • HashSet<int> and TreeSet<int> both providing insert() and exists().
  • TreeSet<T> and IntList providing begin() and end().
  • Lots of our classes providing printToStream().
  • Horse speaking

    Hay, wait a minute! If we say mySet.exists(42), how does the compiler know whether to call HashSet<int>::exists or TreeSet<int>::exists?

  • LHS Cow speaking

    Good question! Let's ask the students!

How does our C++ program know which exists() function it should be calling? Where is the information that would answer this question?

Our program probably looks something like

TreeSet<int> mySet;

// ... more code ...

std::cout << mySet.exists(42);

Notice that we do know the type of mySet, namely that it's a TreeSet<int>. That's the key piece of information that tells us which exists() function to call.

  • Duck speaking

    Exactly. The type is right there in the program, and so it knows to call TreeSet<int>'s exists() function. That's pretty obviously the right choice.

  • LHS Cow speaking

    Is it…?

  • Bjarne speaking

    I think so! Use the type of the variable (as shown in the program's code) to know what function to call!

  • LHS Cow speaking

    We'll see just how good an idea it is.

  • Horse speaking

    Hay, I have another question! What if I wanted to write more general code, that didn't mind what kind of set class it had so long as it could call insert() and exists() on it. Could I do that?

If two classes have the same interface (i.e., the same member functions), can we write a function that could be passed an either one of them?

Yes! We can write a template function that doesn't care what kind of “set” it's working on:

template <typename Set>
void doStuff(Set& someSet) {
    // ... code ...
    std::cout << someSet.exists(42);
}

Our generic doStuff() function doesn't say what Set will be (and so doesn't know which exists() function we want to call), but when we write

TreeSet<int> mySet;

// ... more code ...

doStuff(mySet);

the C++ compiler stamps out an instance of doStuff() where Set is TreeSet<int>, so once again the compiler does know the real type of someSet and thus which exists() function to call.

  • Dog speaking

    Cool!

  • Cat speaking

    Okay, but we were asked to make a function. Is this really one function? Isn't a function template an infinite family of functions, one for every possible Set type? If we make both a doStuff<TreeSet<int>> instantiation and a doStuff<HashSet<int>> instantiation, haven't we stamped out two functions?

  • LHS Cow speaking

    Well, technically, yes, but we only wrote one…

  • Jo speaking

    In Java you can use inheritance and subclasses, does C++ have that too?

  • Bjarne speaking

    It does!

  • Pig speaking

    I want to know MORE!

  • LHS Cow speaking

    Okay…

(When logged in, completion status appears here.)