// CSE 333 Lecture 12 demo: Str.cc // Hal Perkins // Implementation of a simple string class. #include #include #include "Str.h" using namespace std; // Print trace messages with object addresses to show when functions get called. #define TRACE(what) cout << "- Str::" what << " called on " << this << endl // constructors Str::Str() { TRACE("default constructor"); // allocate empty string st_ = new char[1]; st_[0] = '\0'; } Str::Str(const char *s) { TRACE("c-string constructor"); int len = strlen(s); st_ = new char[len+1]; strcpy(st_, s); } Str::Str(const Str &s) { TRACE("copy constructor"); int len = strlen(s.st_); st_ = new char[len+1]; strcpy(st_, s.st_); } // destructor Str::~Str() { TRACE("destructor"); delete [] st_; } // operations int Str::length() const { TRACE("length"); return strlen(st_); } char * Str::c_str() const { TRACE("c_str"); char * result = new char[strlen(st_)+1]; strcpy(result, st_); return result; } void Str::append(const Str &s) { TRACE("append"); char *newst = new char[strlen(st_) + strlen(s.st_) + 1]; strcpy(newst, st_); strcat(newst, s.st_); delete [] st_; st_ = newst; } Str & Str::operator=(const Str &s) { TRACE("assignment"); // do nothing if trying to assign a string to itself if (this == &s) { return *this; } // Replace string array with one of correct size // (Note: this is where the self-assignment test _really_ matters) // (Note: a better implementation would re-use the existing array // if it's long enough, but not too long) delete [] st_; st_ = new char[strlen(s.st_)+1]; // copy characters and return strcpy(st_, s.st_); return *this; } // stream output // (Note: not a member function of Str. This is an overloaded global // function that is a friend of Str so it can access private data) ostream &operator<<(ostream &out, const Str &s) { out << s.st_; return out; }