Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |
One of the most valuable and convenient aspects of C++ strings
is that they grow as needed, without intervention on the part of the
programmer. Not only does this make string-handling code inherently more
trustworthy, it also almost entirely eliminates a tedious housekeeping
chore keeping track of the bounds of the storage where your strings live. For
example, if you create a string object and initialize it with a string of 50
copies of X , and later store in it 50 copies of Zowie , the object itself
will reallocate sufficient storage to accommodate the growth of the data.
Perhaps nowhere is this property more appreciated than when the strings
manipulated in your code change size and you don t know how big the change is. The
string member functions append( ) and insert( )
transparently reallocate storage when a string grows:
//: C03:StrSize.cpp
#include <string>
#include <iostream>
using namespace std;
int main() {
string bigNews("I saw Elvis in a UFO. ");
cout << bigNews << endl;
// How much data have we actually got?
cout << "Size = " <<
bigNews.size() << endl;
// How much can we store without reallocating?
cout << "Capacity = " <<
bigNews.capacity() << endl;
// Insert this string in bigNews immediately
// before bigNews[1]:
bigNews.insert(1, " thought I");
cout << bigNews << endl;
cout << "Size = " <<
bigNews.size() << endl;
cout << "Capacity = " <<
bigNews.capacity() << endl;
// Make sure that there will be this much space
bigNews.reserve(500);
// Add this to the end of the string:
bigNews.append("I've been working too
hard.");
cout << bigNews << endl;
cout << "Size = " <<
bigNews.size() << endl;
cout << "Capacity = " <<
bigNews.capacity() << endl;
} ///:~
Here is the output from one particular compiler:
I saw Elvis in a UFO.
Size = 22
Capacity = 31
I thought I saw Elvis in a UFO.
Size = 32
Capacity = 47
I thought I saw Elvis in a UFO. I've been
working too hard.
Size = 59
Capacity = 511
This example demonstrates that even though you can safely
relinquish much of the responsibility for allocating and managing the memory
your strings occupy, C++ strings provide you with several tools
to monitor and manage their size. Notice the ease with which we changed the
size of the storage allocated to the string. The size( ) function returns the number of characters currently stored in the string and is identical to the length( ) member function. The capacity( ) function returns
the size of the current underlying allocation, meaning the number of characters
the string can hold without requesting more storage. The reserve( )
function is an optimization mechanism that indicates your intention to specify
a certain amount of storage for future use; capacity( ) always
returns a value at least as large as the most recent call to reserve( ).
A resize( ) function appends spaces if the new size is greater than
the current string size or truncates the string otherwise. (An overload of resize( )
can specify a different character to append.)
The exact fashion that the string member functions
allocate space for your data depends on the implementation of the library. When
we tested one implementation with the previous example, it appeared that
reallocations occurred on even word (that is, full-integer) boundaries, with
one byte held back. The architects of the string class have endeavored
to make it possible to mix the use of C char arrays and C++ string
objects, so it is likely that figures reported by StrSize.cpp for capacity
reflect that, in this particular implementation, a byte is set aside to easily
accommodate the insertion of a null terminator.
Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |