The implementation file can be compiled and provided to a user program as a linkable object file. The implementation file must include the interface file it defines as well as interface files for any other classes it references. The structure of the interface file for our string example will require the normal c-style string include file along with "mystring.h" defined above:
#include <string.h>
#include "mystring.h"
.
.
.
MEMBER FUNCTION DEFINITIONS
.
.
.
NON-MEMBER FUNCTION DEFINITIONS
.
.
.
Looking at the entries for the various components, we have
The constructors initialize the data structure.
string::string(const char * cstring)
{
if (cstring == NULL)
cstring = "";
strLength = strlen(cstring);
bufferLength = strLength+1;
buffer = new char[bufferLength];
strcpy(buffer, cstring);
}
Class Exercise -
A redefinition of the assignment of a string onto a string is required for exactly the same reason as the copy constructor. The first if statement in the function implementation ensures that the assignment of a string onto itself is correctly handled.
const string & string::operator=(const string & rhs)
{
if (this != &rhs) {
if (bufferLength < rhs.length() +1)
delete [] buffer;
bufferLength = rhs.length()+1;
buffer = new char[bufferLength];
}
strLength = rhs.length();
strcpy(buffer, rhs.buffer);
}
return *this;
}
The append operation (+= assignment) is slightly more
complicated, but similar. It can be found in the text.
Array indexing operations overload the brackets, [] to return either the kth character of the string, or a reference to the kth character. The bodies of the functions are identical and the only difference is in the declaration.
char & string::operator[](int k)
{
if (k<0 || k>=strLength)
throw StringIndexOutOfBounds();
return buffer[k];
}
char string::operator[](int k) const
{
if (k<0 || k>=strLength)
throw StringIndexOutOfBounds();
return buffer[k];
}
Class Exercise -
Input and output operators allow us to send our string type to an I/O stream as if it were a built-in type. Input (output) operators return the istream (ostream) variable so that the operations can be chained. I.e.
string s1 = "Clydes"; string s2 = "dales"; cout << s1 << s2 << " weigh more than " << 5 << " pounds" << endl;
The more complicated input operator is shown below. The
remaining functions are similar and may be found in the text.
istream & operator >>(istream & in, string & str)
{
char buf[string::MAX_LENGTH + 1];
in >> buf;
str = buf;
return in;
}
The comparison operators allow us to put our string variables in lexically correct order, such that dog > cat, cat< mouse. All the comparison operators rely on the c-string function strcmp. For completeness, here is the < operator. The rest are very similar and can be found in the text.
bool operator<( const string & lhs, const string & rhs)
{
return strcmp(lhs.c_str(), rhs.c_str()) < 0;
}