Comp 272 Program 5 Fall 2004 Dordal Due: Fri, Dec 10, 2004 For your last program, you are to build a simple string class, to be called "string2". This class should contain a copy ctor, ctors from (the existing class) string and (native C strings) char*, a destructor (dtor), ie string2(string2 &) string2(string) string2(char*) ~string2() and support for the following operations (all within the class string2 except for operator<<, to be defined outside): operator= operator== operator[] operator<<(ostream&, string2&) operator+=(string2 &) // append a string operator+=(char) // append a char Your string2 class will be based on the T_array example program, to be discussed in class. T_arrays are a class similar to Vector; a string is a form of Vector. Several of the operations above are already implemented for T_arrays. Note that string2s will have a couple features, described below, that T_arrays do NOT have. The string2 class is intended to support frequent appending to the end of the string, and so the class will be optimized to handle this case efficiently. What this means is that more space (in general) will be allocated to a string than is actually needed, to allow room for growth without reallocation. (String2s that grow beyond their maximum allocation *will* require reallocation, but it is expected that this will be infrequent.) We will call our strategy the Append Optimization. In detail, string2s will have a current _size, representing the number of "real" characters in the current string, and also a _maxsize >= _size representing the size to which the string can grow without memory reallocation. Appending a single character to a string2 is similar to vector::push_back(), except that push_back() forces a reallocation every time (as we saw in class with the demo that printed every call to the copy ctor). The underlying implementation of string2s is to use native C strings, that is, char* (pointer to char). Thus, a string2 object will have the following private data: char* _data; // pointer to "chunk" of memory of size _maxsize int _currsize; int _maxsize; // amount actually allocated. When a string is first created, you should be sure that _maxsize is bigger than the size needed, say twice _currsize, or equal to _currsize+100, or the next highest power of 2. This allows some room for growth, so that adding one character doesn't always force reallocation. A native C array of characters is type char*, identical to char[] on the theory that an array is really a pointer to an array, and a pointer to a character is identified with a pointer to the start of an array (string) of characters. Thus, if you allocate space for 100 characters: _data = new char[100]; then you can access the ith character (starting at 0) as _data[i]. Native C strings assume one more thing: that the first byte *after* the end of the string is a 0 byte, to mark the end. With this 0 byte in place you can use the functions int strlen(char*) and strcpy() to find the length of a string and copy it. Or, you can just skip that and just handle the bytes directly. Demonstrate your program on some simple examples, showing += cases that both do and do not force reallocation. For diagnostic purposes, you should have your append (operator+=) print out a message when it does reallocate, and then demonstrate the reallocations involved in: string2 s; for (i=0; i<1000; i++) s+= 'x'; // build 1000-char string2 There should be some reallocation, because you don't want to allocate 1000 bytes for every string2, but there should be *much* less than 1000 reallocations. Be sure to test the ctors too.