#include #include #include #include using namespace std; class String { public: String( ) { ptr = new StringObject( "" ); } String( char c ) { char str[] = { c, '\0' }; ptr = new StringObject( str ); } String( const char *str ) { ptr = new StringObject( str ); } String( const String & other ) { ptr = other.ptr; incrementRefCount( ); } ~String( ) { decrementRefCount( ); } String operator+( const String & rhs ) const { String result = *this; result += rhs; return result; } const String & operator+= ( const String & rhs ) { int newLength = length( ) + rhs.length( ); separate( newLength * 2 + 1 ); if( this == &rhs ) { String copy( rhs ); return *this += copy; } if( newLength >= ptr->bufferLen ) { ptr->bufferLen = 2 * ( newLength + 1 ); char *oldBuffer = ptr->buffer; ptr->buffer = new char[ ptr->bufferLen ]; strcpy( ptr->buffer, oldBuffer ); delete [ ] oldBuffer; } strcpy( ptr->buffer + length( ), rhs.ptr->buffer ); ptr->strLen = newLength; return *this; } const String & operator= ( const String & rhs ) { if( this != &rhs ) { decrementRefCount( ); ptr = rhs.ptr; incrementRefCount( ); } return *this; } int length( ) const { return ptr->strLen; } const char * c_str( ) const { return ptr->buffer; } char operator[]( int idx ) const { return ptr->buffer[ idx ]; } char & operator[]( int idx ) { separate( ); return ptr->buffer[ idx ]; } bool operator==( const String & rhs ) const { return strcmp( ptr->buffer, rhs.ptr->buffer ) == 0; } bool operator==( const char *rhs ) const { return strcmp( ptr->buffer, rhs ) == 0; } private: struct StringObject { StringObject( const char *str ) { construct( str, strlen( str ) + 1 ); } StringObject( const char *str, int buflen ) { construct( str, buflen ); } void construct( const char *str, int buflen ) { cout << "CONSTRUCTING STRINGOBJECT " << str << endl; strLen = strlen( str ); bufferLen = buflen; buffer = new char[ bufferLen ]; strcpy( buffer, str ); refCount = 1; } ~StringObject( ) { delete [ ] buffer; } // Would expect operator= and copy constructor char *buffer; // storage for characters int bufferLen; // size of the buffer int strLen; // length of string < bufferLen int refCount; // reference count }; void incrementRefCount( ) { ptr->refCount++; } void decrementRefCount( ) { if( --ptr->refCount == 0 ) delete ptr; } void separate( int newBufferLen ) { if( ptr->refCount == 1 ) return; ptr->refCount--; ptr = new StringObject( ptr->buffer, newBufferLen ); } void separate( ) { separate( ptr->bufferLen ); } StringObject *ptr; }; ostream & operator<< ( ostream & out, const String & x ) { out << x.c_str( ); return out; } istream & operator>> ( istream & in, String & str ) { char ch; str = ""; in >> ch; if( !in.fail( ) ) { do { str += ch; in.get( ch ); } while( !in.fail( ) && !isspace( ch ) ); if( isspace( ch ) ) in.putback( ch ); } return in; } bool operator==( const char *lhs, const String & rhs ) { return strcmp( lhs, rhs.c_str( ) ) == 0; } bool operator!=( const String & lhs, const String & rhs ) { return strcmp( lhs.c_str( ), rhs.c_str( ) ) != 0; } int main( ) { String s1 = "hello"; String s2 = "world"; String s3 = s1; cout << boolalpha; cout << s1.length( ) << endl; cout << s1 << endl; cout << s2 << endl; cout << s3 << endl; cout << endl; cout << (s1==s2) << endl; cout << (s1!=s3) << endl; cout << (s1=="world") << endl; cout << ("world"==s1) << endl; cout << endl; for( int i = 0; i < s1.length( ); i++ ) cout << s1[ i ] << endl; s3[ 0 ] = 'j'; cout << s3 << endl; s3 += s2; cout << s3 << endl; return 0; }