Class description: A MyString class should behave much like the c++ string class
ID: 3673477 • Letter: C
Question
Class description: A MyString class should behave much like the c++ string class. The class should use a dynamically allocated char array to hold a character string. If the amount of memory allocated to the array is too small to complete some necessary task (e.g., assigning a new character string to the object) the object should automatically double its capacity until it is large enough to complete the task. If it's discovered that the object is using less than 25% of its capacity the object should shrink to half its capacity until it is using more that 25% of its capacity.
Assignment: Implement the MyString class using a header and implementation file named MyString.h and MyString.cpp respectively. Even though MyString.h will be provided on the upload site, create own version for testing code locally. Make sure to properly test code on by creating a test driver that fully tests every function created in the MyString class
Memory Requirements: 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 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:
MyString( ) Constructor
MyString(const char *) Constructor with an initialization character string
~MyString( ) Destructor
MyString(const MyString &) Copy constructor
MyString& operator = (const MyString&) Overloaded assignment operator, make a copy of MyString object
bool operator == (const MyString&) const overloaded equivalence relational operator
char& operator [ ] (int) overloaded [ ] should return a char by reference
void operator += (const MyString&) overloaded += operator, use to concatenate two MyStrings
MyString operator + (const MyString&) const Create a new MyString object that is the concatenation of two MyString objects
void getline(istream&, char delimit = ‘ ’); reads an entire line from a istream. Lines are terminated with delimit which is newline ‘ ’ by default
int length( ) const; return the length of the string
friend ostream& operator<< (ostream&, MyString&); overloaded insertion operator
Explanation / Answer
#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 = ' ');
/*************************************************************************
* 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] = '';
}
/*****************************************************************************
* 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] != ''; 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] = '';
}
/*****************************************************************************
* 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] != ''; i++)
{
data[i] = aMyString.data[i];
}
data[size] = '';
}
/*****************************************************************************
* 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] != ''; i++)
{
data[i] = aMyString.data[i];
}
data[size] = '';
}
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] != ''; i++)
{
temp[i] = aMyString.data[j];
j++;
}
size += aMyString.size;
temp[size] = '';
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] = '';
}
/*****************************************************************************
* 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] != ''; 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;
}