// WARNING: Requires exceptions (use g++ -fhandle-exceptions) #include #include class String { public: String(void) : myStr(0) {} String(char* cstr) : myStr(strdup(cstr)) {} String(const String& str) : myStr(strdup(str.myStr)) {} ~String(void) { delete myStr; } // PROXY CLASS FOR REFERENCES TO INDIVIDUAL CHARS WITHIN A String class CharProxy { public: CharProxy(char&); operator char& (void); CharProxy operator=(const char&); CharProxy operator=(CharProxy); private: char& myRef; }; CharProxy operator[] (int index); char operator[] (int index) const; int length(void) const { return strlen(myStr); } private: char* myStr; }; struct NullAssignment { NullAssignment(void) { cout << "threw NullAssignment()" << endl; } }; struct BadIndex { BadIndex(int index) { cout << "threw BadIndex(" << index << ")" << endl; } }; String::CharProxy::CharProxy(char& ref) : myRef(ref) {} String::CharProxy::operator char& (void) { return myRef; } String::CharProxy String::CharProxy::operator=(const char& c) { if (c=='\0') { throw NullAssignment(); } myRef = c; return *this; } String::CharProxy String::CharProxy::operator=(CharProxy c) { if (c.myRef=='\0') { throw NullAssignment(); } myRef = c.myRef; return *this; } String::CharProxy String::operator[](int index) { if (index<0||index>=length()) { throw BadIndex(index); } return myStr[index]; } char String::operator[] (int index) const { if (index<0||index>=length()) { throw BadIndex(index); } return myStr[index]; } int main(void) { String s ("cat"); cout << s[0] << endl; cout << s[4] << endl; s[0] = 'r'; s[4] = 'e'; s[0] = '\0'; s[4] = '\0'; }