Given our alloc_n_copy
and free
members, the copy-control members of our class are straightforward. The copy constructor calls alloc_n_copy
:
StrVec::StrVec(const StrVec &s)
{
// call alloc_n_copy to allocate exactly as many elements as in s
auto newdata = alloc_n_copy(s.begin(), s.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
and assigns the results from that call to the data members. The return value from alloc_n_copy
is a pair
of pointers. The first
pointer points to the first constructed element and the second
points just past the last constructed element. Because alloc_n_copy
allocates space for exactly as many elements as it is given, cap
also points just past the last constructed element.
The destructor calls free
:
StrVec::~StrVec() { free(); }
The copy-assignment operator calls alloc_n_copy
before freeing its existing elements. By doing so it protects against self-assignment:
StrVec &StrVec::operator=(const StrVec &rhs)
{
// call alloc_n_copy to allocate exactly as many elements as in rhs
auto data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
Like the copy constructor, the copy-assignment operator uses the values returned from alloc_n_copy
to initialize its pointers.