Array Elements That “Don't Have a Cow
”
Letting Our Barn Have Empty Elements
I think we'd like
cowCapacity_
to be the maximum number ofCow
s, but have the array able to have some unfilled slots, with some elements being empty.And it would be great if we could add
Cow
s that are initialized however we want, not just as defaultCow
s.Meh. I don't see how that's possible. If we have an
Cow
array of size 4, we'll have that manyCow
s.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 actualCow
objects…Oh, dear, I might know where this is going…
We'll make residentCows_
an array of pointers to Cow
s. That way,
- When the array is initialized, we'll have a bunch of default-initialized pointers, not default
Cow
s. - We can then point those pointers at real
Cow
objects (initialized however we want), whenever we want to.
We'll also need a way to keep track of how many Cow
s 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
};
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!
}
Okay, so now a
Barn
starts with noCow
s at all! It only has default-initializedCow*
s. How will we add the actualCow
s?Yup! We'll deal with adding
Cow
s next!Hay! Aren't default-intialized pointers bad? Don't they have an indeterminate value that could be anything?
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
Cow
s.Fun fact, if we used
new Cow*[cowCapacity_]{}
instead ofnew Cow*[cowCapacity_]
, then the pointers would be initialized tonullptr
instead of having an indeterminate value. It's a super-wierd subtlty I put in the language to give programmers more choice.Yeah, uh, thanks Bjarne. We don't really need to know that right now.
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.)