#include #include #include #include using namespace std; class String { public: String( ) { ptr = new StringObj( "" ); } String( char c ) { char str[ 2 ] = { c, '\0' }; ptr = new StringObj( str ); } String( char *str ) { ptr = new StringObj( str ); } String( const String & other ) { ptr = other.ptr; ptr->refCount++; } ~String( ) { decRefCount( ); } String operator+( const String & rhs ) const { String result = *this; result += rhs; return result; } const String & operator+= ( const String & rhs ) { if( this == &rhs ) { String copy( rhs ); return *this += copy; } separate( ); int newLength = length( ) + rhs.length( ); 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 ) { decRefCount( ); ptr = rhs.ptr; ptr->refCount++; } 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( c_str( ), rhs.c_str( ) ) == 0; } bool operator==( const char *rhs ) const { return strcmp( c_str( ), rhs ) == 0; } private: void decRefCount( ) { if( --ptr->refCount == 0 ) delete ptr; } void separate( ) { if( ptr->refCount == 1 ) return; ptr->refCount--; ptr = new StringObj( ptr->buffer, ptr->bufferLen ); } struct StringObj { StringObj( char *str ) { construct( str, strlen( str ) + 1 ); } StringObj( char *str, int blen ) { construct( str, blen ); } ~StringObj( ) { cout << "Cleaning up " << buffer << endl; delete [ ] buffer; } void construct( char *str, int blen ) { cout << "Calling construct " << str << endl; bufferLen = blen; strLen = strlen( str ); buffer = new char[ bufferLen ]; strcpy( buffer, str ); refCount = 1; } char *buffer; // storage for characters int bufferLen; // size of the buffer int strLen; // length of string < bufferLen int refCount; }; StringObj *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; String s4 = s1; cout << s1.length( ) << endl; cout << s1 << endl; cout << s2 << endl; cout << s3 << endl; cout << (s1==s2) << endl; cout << (s1!=s3) << endl; cout << (s1=="world") << endl; cout << ("world"==s1) << endl; for( int i = 0; i < s1.length( ); i++ ) cout << s1[ i ] << endl; s3[ 0 ] = 'j'; cout << s3 << endl; s4 = s3; s3 += s2; cout << endl; cout << s1 << endl; cout << s2 << endl; cout << s3 << endl; cout << s4 << endl; return 0; }