CS 70

Array Elements That “Don't Have a Cow

Letting Our Barn Have Empty Elements

  • Cat speaking

    I think we'd like cowCapacity_ to be the maximum number of Cows, but have the array able to have some unfilled slots, with some elements being empty.

  • LHS Cow speaking

    And it would be great if we could add Cows that are initialized however we want, not just as default Cows.

  • Goat speaking

    Meh. I don't see how that's possible. If we have an Cow array of size 4, we'll have that many Cows.

  • LHS Cow speaking

    Good point! We need a way for array elements to not have a Cow in them. To accomplish that goal, our array can't hold actual Cow objects…

  • Hedgehog speaking

    Oh, dear, I might know where this is going…

We'll make residentCows_ an array of pointers to Cows. That way,

  • When the array is initialized, we'll have a bunch of default-initialized pointers, not default Cows.
  • We can then point those pointers at real Cow objects (initialized however we want), whenever we want to.

What will we need to change the type of residentCows_ to?

We'll also need a way to keep track of how many Cows we have in the Barn, separate from the size of the array.

We'll introduce a new data member, cowCount_, which will serve that purpose.

So our Barn class will change to

class Barn {
 public:
    Barn();
    Barn(size_t numCows);
    void feed();

    // Disable copying and assignment
    Barn(const Barn& other) = delete;
    Barn& operator=(const Barn& rhs) = delete;

 private:
    size_t cowCapacity_;  // The number of Cows the Barn can hold
    size_t cowCount_;     // The number of Cows in the Barn
    Cow** residentCows_;  // Points to an array of Cow*s on the heap
};

What should go in the member initialization list for residentCows_?

We'll also initialize cowCount_ to 0.

So our constructor will change to

Barn::Barn(size_t numCows)
    : cowCapacity_{numCows},
      cowCount_{0},
      residentCows_{new Cow*[cowCapacity_]}
{
    // Nothing (else) to do here!
}
  • Cat speaking

    Okay, so now a Barn starts with no Cows at all! It only has default-initialized Cow*s. How will we add the actual Cows?

  • LHS Cow speaking

    Yup! We'll deal with adding Cows next!

  • Horse speaking

    Hay! Aren't default-intialized pointers bad? Don't they have an indeterminate value that could be anything?

  • LHS Cow speaking

    So long as we never follow a default-initialized pointer, we're fine. We'll only follow pointers that we've initialized to point to real Cows.

  • Bjarne speaking

    Fun fact, if we used new Cow*[cowCapacity_]{} instead of new Cow*[cowCapacity_], then the pointers would be initialized to nullptr instead of having an indeterminate value. It's a super-wierd subtlty I put in the language to give programmers more choice.

  • LHS Cow speaking

    Yeah, uh, thanks Bjarne. We don't really need to know that right now.

  • RHS Cow speaking

    Okay, we've made some good progress. Let's head back up to the parent page to see how far we've come and maybe take a break.

(When logged in, completion status appears here.)