In: Computer Science
Problem Statement:
Implement the MyString class using a header and implementation file named MyString.h and MyString.cpp respectively. Make sure to properly test your code on your own by creating a test driver that tests every function created in the MyString class.
Deliverables:
proj3-MyString.h
proj3-MyString.cpp
proj3-testMain.cpp
Memory Requirements:
Your MyString should start with 10 bytes of allocated memory and should grow in size by doubling. So, we should be able to predict the capacity of your MyString as acquiring a patten of 10, 20, 40, 80, … bytes of memory depending of the number of characters stored.
Attributes:
int size; // The number of characters currently stored in the string // object. Do NOT count the NULL character. int capacity; // The number of bytes currently allocated. This should always be at least // size + 1. The extra byte is needed to store the NULL character. char *data; // Character pointer that points to an array of characters.
Member Functions:
// Default Constructor MyString( ); // Constructor with an initialization character string MyString(const char *); // Destructor ~MyString( ); // Copy constructor MyString(const MyString &); // Overloaded assignment operator, make a copy of MyString object MyString& operator = (const MyString&); // Overloaded equivalence relational operator bool operator == (const MyString&) const; // Overloaded [ ] should return a char by reference char& operator [ ] (int); // Overloaded += operator, use to concatenate two MyStrings void operator += (const MyString&); // Create a new MyString object that is the concatenation of two MyString objects MyString operator + (const MyString&) const; // Reads an entire line from a istream. Lines are terminated with delimit which is newline // ‘\n’ by default void getline(istream&, char delimit = ‘\n’); // Return the length of the string int length( ) const; // Overloaded insertion operator friend ostream& operator<< (ostream&, MyString&);
#ifndef MYSTRING_H_INCLUDED
#define MYSTRING_H_INCLUDED
#include <ostream>
#include <istream>
using namespace std;
class SerializableIfc
{
public:
virtual void writeObject( ostream & ) =
0;
virtual void readObject( istream & ) =
0;
};
class MyString : public SerializableIfc
{
private:
int size;
int capacity;
char *data;
public:
/*************************************************************************
* Function: Default Constructor
* Description: Called upon initialization of a
MyString object. Sets
*
initial values to MyString members.
*************************************************************************/
MyString();
/*************************************************************************
* Function: Deconstructor
* Description: Deletes the data member of a n
object to free dynamically
*
allocated memory.
*************************************************************************/
~MyString();
/*************************************************************************
* Function: Constructor with initialization
string
* Description: Called upon initialization of a
MyString object with a value
*
passed through. Sets initial values to MyString members.
*************************************************************************/
MyString(const char *);
/*************************************************************************
* Function: Copy Constructor
* Description: Called when one MyString object
is initialized with another
*
MyString object.
*************************************************************************/
MyString(const MyString &);
/*************************************************************************
* Function: Overloaded Assignment Operator
* Description: Called when one MyString object
is assigned to another
*
MyString object.
*************************************************************************/
MyString operator =(const MyString &);
/*************************************************************************
* Function: Overloaded Equivalence
Operator.
* Description: Called when one object is
compared to another object and
*
returns true or false.
*************************************************************************/
bool operator==(const MyString &) const;
/*************************************************************************
* Function: Overloaded array operator
* Description: Returns a character of a
specified index within a MyString
*
object.
*************************************************************************/
char& operator [ ] (int);
/*************************************************************************
* Function: Overloaded Concatenation
Operator
* Description: Concatenates two MyString Objects
and returns the newly
*
concatenated MyString.
*************************************************************************/
void operator+=(const MyString &);
/*************************************************************************
* Function: Overloaded Addition Operator
* Description: Creates a new MyString object
which holds the sum of two
*
MyStrings.
*************************************************************************/
MyString operator+(const MyString &)
const;
/*************************************************************************
* Function: Getline Function
* Description: Reads an entire line of a file
delimited by backslash n
*************************************************************************/
void getline(istream&, char delimit =
'\n');
/*************************************************************************
* Function: length
* Description: Returns the length of a
string
*************************************************************************/
int length() const;
/*************************************************************************
* Function: Overloaded Insertion Operator
* Description: Outputrs the contents of a
MyString
*************************************************************************/
friend ostream& operator<<(ostream
&, MyString &);
// Serializable pure virtual void
functions
void writeObject( ostream & );
void readObject( istream & );
};
#endif // MYSTRING_H_INCLUDED
MyString.cpp
#include "MyString.h"
/*****************************************************************************
* Function: Default Constructor
* Description: Called upon initialization of a MyString object.
Sets
*
initial values to MyString members.
* Pre-C: No MyString exists
* Post-C: A MyString now exists
* Returns: MyString
*****************************************************************************/
MyString::MyString()
{
size = 0;
capacity = 10;
data = new char[capacity];
data[size] = '\0';
}
/*****************************************************************************
* Function: Deconstructor
* Description: Deletes the data member of a n object to free
dynamically
*
allocated memory.
* Pre-C: a MyString exists
* Post-C: MyString is changed
* Returns: MyString
*****************************************************************************/
MyString::~MyString()
{
delete [] data;
data = NULL;
}
/*****************************************************************************
* Function: Constructor with initialization string
* Description: Called upon initialization of a MyString object with
a value
*
passed through. Sets initial values to MyString members.
* Pre-C: No MyString exists
* Post-C: A MyString now exists
* Returns: MyString
*****************************************************************************/
MyString::MyString(const char *charPtr)
{
size = 0;
capacity = 10;
data = new char[capacity];
for (int i = 0; charPtr[i] != '\0';
i++)
{
data[i] =
charPtr[i];
size ++;
// Grow
while (size >=
capacity)
{
capacity *= 2;
char *temp = new char[capacity];
for (int i = 0; i < size; i++)
{
temp[i] = charPtr[i];
}
delete [] data;
data = temp;
}
}
// Shrink
while (size * 4 < capacity)
{
capacity /= 2;
char *temp = new
char[capacity];
for (int i = 0; i
< size; i++)
{
temp[i] = data[i];
}
delete [] data;
data = temp;
}
data[size] = '\0';
}
/*****************************************************************************
* Function: Copy Constructor
* Description: Called when one MyString object is initialized with
another
*
MyString object.
* Pre-C: No MyString exists
* Post-C: a MyString now exists
* Returns: MyString
*****************************************************************************/
MyString::MyString(const MyString &aMyString)
{
// Set the capacity/size of new MyString = that
of aMyString
capacity = aMyString.capacity;
size = aMyString.size;
// Allocate memory for new MyString
data = new char[capacity];
for (int i = 0; aMyString.data[i] != '\0';
i++)
{
data[i] =
aMyString.data[i];
}
data[size] = '\0';
}
/*****************************************************************************
* Function: Overloaded Assignment Operator
* Description: Called when one MyString object is assigned to
another
*
MyString object.
* Pre-C: a MyString exists
* Post-C: MyString is changed
* Returns: MyString
*****************************************************************************/
MyString MyString::operator=(const MyString &aMyString)
{
// Make sure not to assign an object to
itself
if (this != &aMyString)
{
// clear and delete
data
delete [] data;
// Set the capacity/size
of new MyString = that of aMyString
capacity =
aMyString.capacity;
size =
aMyString.size;
// Allocate memory for
new MyString
data = new
char[capacity];
for (int i = 0;
aMyString.data[i] != '\0'; i++)
{
data[i] = aMyString.data[i];
}
data[size] =
'\0';
}
return *this;
}
/*****************************************************************************
* Function: Overloaded Equivalence Operator.
* Description: Called when one object is compared to another object
and
*
returns true or false.
* Pre-C: a MyString exists
* Post-C: MyString remains unchanged
* Returns: bool
*****************************************************************************/
bool MyString::operator==(const MyString &aMyString)
const
{
bool result = true;
// if sizes are equivalent continue
if (size == aMyString.size)
{
//Check the value at
each index to see if both MyStrings are
// equivalent
for (int i = 0; i <
size && result; i++)
{
if (data[i] != aMyString.data[i])
{
result = false;
}
}
}
else
{
result = false;
}
return result;
}
/*****************************************************************************
* Function: Overloaded array operator
* Description: Returns a character of a specified index within a
MyString
*
object.
* Pre-C: a MyString exists
* Post-C: MyString remains unchanged
* Returns: char&
*****************************************************************************/
char& MyString::operator [ ] (int index)
{
// Returns a char by reference IF and ONLY
IF
// the index, x, is within the bounds of the
char array
if (index >= 0 && index <
size)
return *(data +
index);
}
/*****************************************************************************
* Function: Overloaded Concatenation Operator
* Description: Concatenates two MyString Objects and returns the
newly
*
concatenated MyString.
* Pre-C: a MyString exists
* Post-C: MyString is changed
* Returns: void
*****************************************************************************/
void MyString::operator+=(const MyString &aMyString)
{
capacity = size + aMyString.size + 1;
char *temp = new char[capacity];
for (int i = 0; i < size; i++)
{
temp[i] = data[i];
}
delete [] data;
int j = 0;
for (int i = size; aMyString.data[j] != '\0';
i++)
{
temp[i] =
aMyString.data[j];
j++;
}
size += aMyString.size;
temp[size] = '\0';
data = temp;
}
/*****************************************************************************
* Function: Overloaded Addition Operator
* Description: Creates a new MyString object which holds the sum of
two
*
MyStrings.
* Pre-C: a MyString exists
* Post-C: MyString is changed
* Returns: MyString
*****************************************************************************/
MyString MyString::operator+(const MyString &aMyString)
const
{
MyString anotherMyString = data;
anotherMyString += aMyString;
return anotherMyString;
}
/*****************************************************************************
* Function: Getline Function
* Description: Reads an entire line of a file delimited by
backslash n
* Pre-C: a MyString exists
* Post-C: MyString is changed
* Returns: void
*****************************************************************************/
void MyString::getline(istream &inFile, char delimit)
{
char aChar;
// Delete everything if theres anything in
data
if (size > 0)
{
delete [] data;
size = 0;
capacity = 10;
data = new
char[capacity];
}
inFile.get(aChar);
while(aChar != delimit)
{
data[size] =
aChar;
size++;
// Grow if
necessary
while (size >=
capacity)
{
capacity *= 2;
char *temp = new char[capacity];
for (int i = 0; i < size; i++)
{
temp[i] = data[i];
}
delete [] data;
data = temp;
}
inFile.get(aChar);
}
// Shrink if necessary
while (size * 4 < capacity)
{
capacity /= 2;
char *temp = new
char[capacity];
for (int i = 0; i
< size; i++)
{
temp[i] = data[i];
}
delete [] data;
data = temp;
}
data[size] = '\0';
}
/*****************************************************************************
* Function: length
* Description: Returns the length of a string
* Pre-C: a MyString exists
* Post-C: MyString remains unchanged
* Returns: int
*****************************************************************************/
int MyString::length() const
{
int length = 0;
for(int i = 0; data[i] != '\0'; i++)
{
length++;
}
return length;
}
/*****************************************************************************
* Function: Overloaded Insertion Operator
* Description: Outputs the contents of a MyString
* Pre-C: a MyString exists
* Post-C: MyString remains unchanged
* Returns: bool
*****************************************************************************/
ostream& operator<<(ostream &output, MyString
&aMyString)
{
for (int i = 0; i < aMyString.size;
i++)
{
output <<
aMyString.data[i];
}
return output;
}
/*****************************************************************************
* Function: writeObject
* Description: Writes size, capacity, and data to a binary
file
* Pre-C: a MyString exists
* Post-C: MyString remains unchanged
* Returns: void
*****************************************************************************/
void MyString::writeObject( ostream &out )
{
out.write((char*)&size, sizeof(size));
out.write((char*)&capacity,
sizeof(capacity));
out.write(data, size);
}
/*****************************************************************************
* Function: readObject
* Description: Reads size, capacity, and data from a binary file
and stores
*
the values in a MyString
* Pre-C: a MyString exists
* Post-C: MyString remains unchanged
* Returns: void
*****************************************************************************/
void MyString::readObject( istream &in )
{
in.read((char*)&size, sizeof(size));
in.read((char*)&capacity,
sizeof(capacity));
delete [] data;
data = new char[capacity];
in.read(data, size);
}
main.cpp
#include <iostream>
#include "MyString.h"
using namespace std;
int main()
{
return 0;
}