In: Computer Science
Using either your own C-string functions of Lab 7.1 or the ones from the standrd C++ cstring library, create a String class, which — while having minimal functionality — illustrates the use of and need for the canonical form.
Overview
Here is the .h file for the class (note the class name — String with a capital S; trying to force the use of the classname string was to much of an issue:
class String {
        friend std::ostream &operator <<(std::ostream &os, const String &s);
        
        friend String operator +(const String &s1, const String &s2);
public:
        String(const char *cs="");
        String(const String &s);
        ~String();
        String &operator =(const String &rhs);
        char &operator [](int index);
        String &operator +=(const String &s);
        
        int length() const;
        
private:
        char *cs;
};
I've also supplied a String_Exception class and an app for testing your class (it will be the test driver once I get it all into Codelab).
Implementation Notes
String::String(const char *cs) : cs(new char[strlen(cs)+1) {    // the +1 is for the null terminator
                                                                #ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
class String {
        friend std::ostream &operator <<(std::ostream &os, const String &s);
//      friend bool operator ==(const String &s1, const String &s2);
        friend String operator +(const String &s1, const String &s2);
public:
        String(const char *cs="");
        String(const String &s);
        ~String();
        String &operator =(const String &rhs);
        char &operator [](int index);
        String &operator +=(const String &s);
//      int find(char c) const;
        int length() const;
//      void clear();
private:
        char *cs;
};
#endifmystring_app.cpp
#include <iostream>
#include <sys/sysinfo.h>
#include <cstdlib>
#include "mystring.h"
using namespace std;
int main() {
        String s = "Hello";
        cout << "s: " << s << " (" << s.length() << ")" << endl;
        cout << "s + \" world\": " << s + " world" << endl;
        cout << "s[1]: " << s[1] << endl;
        String s1 = s;          // making sure copy constructor makes deep copy
        String s2;
        s2 = s;                 // making sure assignment operator makes deep copy
        s[0] = 'j';
        cout << endl;
        cout << "s: " << s << " (" << s.length() << ")" << endl;
        cout << "s1: " << s1 << " (" << s1.length() << ")" << endl;
        cout << "s2: " << s2 << " (" << s2.length() << ")" << endl;
        cout << endl;
        for (int i = 0; i < 5; i++) {
                s += s;
                cout << "s: " << s << " (" << s.length() << ")" << endl;
        }
        cout << endl;
        for (int i = 0; i < 5; i++) 
                s += s;
        cout << "s: " << s << " (" << s.length() << ")" << endl;
        return 0;
}
mystring_exception.cpp
#ifndef MYSTRING_EXCEPTION
#define MYSTRING_EXCEPTION
#include <string>         // Note this is the C++ string class!
class String_Exception {
public:
    String_Exception(std::string what) : what(what) {}
        std::string getWhat() {return what;}
private:
    std::string what;
};
#endif
// mystring_exception.cpp
#ifndef MYSTRING_EXCEPTION
#define MYSTRING_EXCEPTION
#include <string> // Note this is the C++ string class!
class String_Exception {
public:
String_Exception(std::string what) : what(what) {}
std::string getWhat() {return what;}
private:
std::string what;
};
#endif
//end of mystring_exception.cpp
// mystring.h
#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
class String {
friend std::ostream &operator <<(std::ostream &os,
const String &s);
// friend bool operator ==(const String &s1, const String
&s2);
friend String operator +(const String &s1, const String
&s2);
public:
String(const char *cs="");
String(const String &s);
~String();
String &operator =(const String &rhs);
char &operator [](int index);
String &operator +=(const String &s);
// int find(char c) const;
int length() const;
// void clear();
private:
char *cs;
};
#endif
//end of mystring.h
// mystring.cpp
#include "mystring.h"
#include "mystring_exception.cpp"
#include <cstring>
using namespace std;
String::String(const char *cs)
{
   this->cs = new char[strlen(cs)+1];
   strcpy(this->cs,cs);
}
String::String(const String &s)
{
   cs = new char[length()+1];
   strcpy(cs,s.cs);
}
String::~String()
{
   delete cs;
}
String& String::operator =(const String &rhs)
{
   if(this != &rhs)
   {
       delete cs;
       cs = new char[rhs.length()];
       strcpy(cs,rhs.cs);
   }
   return *this;
}
char & String::operator [](int index)
{
   try{
       if(index >=0 && index
< length())
       {
           return
cs[index];
       }else
           throw
String_Exception("Index out of bounds");
   }catch(String_Exception &e)
   {
       cout<<e.getWhat();
   }
}
String & String::operator +=(const String &s)
{
   char *temp = new char[length()+s.length()+1];
   strcpy(temp,cs);
   strcat(temp,s.cs);
   delete cs;
   this->cs = temp;
   return *this;
}
int String::length() const
{
   return strlen(cs);
}
std::ostream &operator <<(std::ostream &os, const
String &s)
{
   os<<s.cs;
   return os;
}
String operator +(const String &s1, const String
&s2)
{
   char *temp = new char[s1.length()+s2.length()+1];
   strcpy(temp,s1.cs);
   strcat(temp,s2.cs);
   return String(temp);
}
//end of mystring.cpp
// mystring_app.cpp
#include "mystring.h"
#include <sys/sysinfo.h>
#include <cstdlib>
#include "mystring.h"
using namespace std;
int main() {
String s = "Hello";
cout << "s: " << s << " (" << s.length() << ")" << endl;
cout << "s + \" world\": " << s + " world" << endl;
cout << "s[1]: " << s[1] << endl;
String s1 = s; // making sure copy constructor makes deep
copy
String s2;
s2 = s; // making sure assignment operator makes deep copy
s[0] = 'j';
cout << endl;
cout << "s: " << s << " (" << s.length()
<< ")" << endl;
cout << "s1: " << s1 << " (" << s1.length()
<< ")" << endl;
cout << "s2: " << s2 << " (" << s2.length()
<< ")" << endl;
cout << endl;
for (int i = 0; i < 5; i++) {
s += s;
cout << "s: " << s << " (" << s.length()
<< ")" << endl;
}
cout << endl;
for (int i = 0; i < 5; i++)
s += s;
cout << "s: " << s << " (" << s.length()
<< ")" << endl;
return 0;
}
//end of mystring_app.cpp
Output:

