CS 70

Polymorphic Storage

  • Duck speaking

    Didn't we say that a big reason for doing this was so we could have a std::vector of animals for our Zoo?

  • LHS Cow speaking

    We did.

  • Pig speaking

    Let's do it. MORE animals!

Open up the code from before:

  • Open Code in OnlineGDB
    • Click the Fork This button on the top left, scroll down to main, and then replace the code in the body of main with the following code:
    auto cowNames = {"Bessie", "Mabel", "Daisy"};
    auto raptorNames = {"Peri", "Rex", "Talon"};
    std::vector<Animal> zoo;

    for (auto name : cowNames) {
        Cow tempCow(name);
        zoo.push_back(tempCow);
    }

    for (auto name : raptorNames) {
        Raptor tempRaptor(name);
        zoo.push_back(tempRaptor);
    }

    for (Animal& animal : zoo) {
        engageWith(animal);
    }

The code makes three Cows and three Raptors, then adds them to our zoo vector, and then calls engageWith() on each of them (which has them speak() and feed()).

Run the revised code. Copy and paste the output into the box below.

Was it what you hoped for?

Any thoughts on what you saw?

You should have seen something like

Bessie makes nonspecific animal noises
Bessie eats
Mabel makes nonspecific animal noises
Mabel eats
Daisy makes nonspecific animal noises
Daisy eats
Peri makes nonspecific animal noises
Peri eats
Rex makes nonspecific animal noises
Rex eats
Talon makes nonspecific animal noises
Talon eats

Generic Animals

  • Horse speaking

    Hay! What did we do wrong? Hadn't we solved this already?

  • Hedgehog speaking

    Oh, no, I think I know what happened—we made Cows and Raptors and then turned them into these zombie-like generic animals.

  • LHS Cow speaking

    Exactly.

Our std::vector only stores base-class Animal objects. Every time we call push_back with a Cow or a Raptor, we only copy the base Animal part of the object into the vector.

  • Cat speaking

    Okay, but I'm not seeing the right way to store an Animal object where it could actually really be a Cow or a Raptor.

  • Bjarne speaking

    You can't.

  • Cat speaking

    What?

  • Horse speaking

    Woah, what?

  • Duck speaking

    Huh?

  • LHS Cow speaking

    Yes, it's pretty much impossible. Because we don't know how many extra data members a derived class might add, we don't even know how much space would be needed per element of the array.

  • RHS Cow speaking

    But there is a way… a slightly indirect way.

  • Goat speaking

    Meh. It's going to be pointers, isn't it?

  • Hedgehog speaking

    Oh, no.

Storing Pointers to Objects

When we're using derived classes, we often end up needing to use pointers.

We can switch out the code above with this code that uses a vector of pointers to animals:

    auto cowNames = {"Bessie", "Mabel", "Daisy"};
    auto raptorNames = {"Peri", "Rex", "Talon"};
    std::vector<Animal*> zoo;

    for (auto name : cowNames) {
        zoo.push_back(new Cow{name});
    }

    for (auto name : raptorNames) {
        zoo.push_back(new Raptor{name});
    }

    for (Animal* animal : zoo) {
        engageWith(*animal);
    }

    while (!zoo.empty()) {
        delete zoo.back();
        zoo.pop_back();
    }

Now run this version.

What happened?

You should have seen

Bessie says: Mooooo
Bessie eats
Mabel says: Mooooo
Mabel eats
Daisy says: Mooooo
Daisy eats
Peri says: Rawrrr
Peri eats
Rex says: Rawrrr
Rex eats
Talon says: Rawrrr
Talon eats

So our code works! We just need to use pointers.

  • Hedgehog speaking

    I tried to escape templates and I ended up with pointers. Oh, joy.

  • LHS Cow speaking

    It's not so bad really.

  • Duck speaking

    I never had these problems in Java.

  • LHS Cow speaking

    Remember, Java is pretty much all pointers all the time. Every time you have an object in Java, it's really a pointer to that object. (They call it a “reference” to try to soften the blow.)

  • Cat speaking

    What I want to know is why we were ever able to make these bland generic Animal objects in the first place—we only want Cows and Raptors.

  • LHS Cow speaking

    Okay, let's see if we can sort out that aspect of things…

(When logged in, completion status appears here.)