zoukankan      html  css  js  c++  java
  • C++ string类的实现

    转自: C++ how to program

    // String class definition with operator overloading.
    #ifndef STRING_H
    #define STRING_H
    
    #include <iostream>
    using std::ostream;
    using std::istream;
    
    class String
    {
       friend ostream &operator<<( ostream &, const String & );
       friend istream &operator>>( istream &, String & );
    public:
       String( const char * = "" ); // conversion/default constructor
       String( const String & ); // copy constructor
       ~String(); // destructor
    
       const String &operator=( const String & ); // assignment operator
       const String &operator+=( const String & ); // concatenation operator
    
       bool operator!() const; // is String empty?
       bool operator==( const String & ) const; // test s1 == s2
       bool operator<( const String & ) const; // test s1 < s2
    
       // test s1 != s2
       bool operator!=( const String &right ) const
       { 
          return !( *this == right ); 
       } // end function operator!=
    
       // test s1 > s2
       bool operator>( const String &right ) const
       { 
          return right < *this; 
       } // end function operator>
     
       // test s1 <= s2
       bool operator<=( const String &right ) const
       { 
          return !( right < *this ); 
       } // end function operator <=
    
       // test s1 >= s2
       bool operator>=( const String &right ) const
       { 
          return !( *this < right ); 
       } // end function operator>=
    
       char &operator[]( int ); // subscript operator (modifiable lvalue)
       char operator[]( int ) const; // subscript operator (rvalue)
       String operator()( int, int = 0 ) const; // return a substring
       int getLength() const; // return string length
    private:
       int length; // string length (not counting null terminator)
       char *sPtr; // pointer to start of pointer-based string
    
       void setString( const char * ); // utility function
    }; // end class String
    
    #endif
    // String class member-function and friend-function definitions.
    #include <iostream>
    using std::cerr;
    using std::cout;
    using std::endl;
    
    #include <iomanip>
    using std::setw;
    
    #include <cstring> // strcpy and strcat prototypes
    using std::strcmp;
    using std::strcpy;
    using std::strcat;
    
    #include <cstdlib> // exit prototype
    using std::exit;
    
    #include "String.h" // String class definition
    
    // conversion (and default) constructor converts char * to String
    String::String( const char *s ) 
       : length( ( s != 0 ) ? strlen( s ) : 0 )
    {
       cout << "Conversion (and default) constructor: " << s << endl;
       setString( s ); // call utility function
    } // end String conversion constructor
    
    // copy constructor
    String::String( const String &copy ) 
       : length( copy.length )
    {
       cout << "Copy constructor: " << copy.sPtr << endl;
       setString( copy.sPtr ); // call utility function
    } // end String copy constructor
    
    // Destructor
    String::~String()
    {
       cout << "Destructor: " << sPtr << endl;
       delete [] sPtr; // release pointer-based string memory
    } // end ~String destructor
    
    // overloaded = operator; avoids self assignment
    const String &String::operator=( const String &right )
    {
       cout << "operator= called" << endl;
    
       if ( &right != this ) // avoid self assignment
       {         
          delete [] sPtr; // prevents memory leak
          length = right.length; // new String length
          setString( right.sPtr ); // call utility function
       } // end if
       else
          cout << "Attempted assignment of a String to itself" << endl;
    
       return *this; // enables cascaded assignments
    } // end function operator=
    
    // concatenate right operand to this object and store in this object
    const String &String::operator+=( const String &right )
    {
       size_t newLength = length + right.length; // new length
       char *tempPtr = new char[ newLength + 1 ]; // create memory
    
       strcpy( tempPtr, sPtr ); // copy sPtr
       strcpy( tempPtr + length, right.sPtr ); // copy right.sPtr
    
       delete [] sPtr; // reclaim old space
       sPtr = tempPtr; // assign new array to sPtr
       length = newLength; // assign new length to length
       return *this; // enables cascaded calls
    } // end function operator+=
    
    // is this String empty?
    bool String::operator!() const
    { 
       return length == 0; 
    } // end function operator! 
    
    // Is this String equal to right String?
    bool String::operator==( const String &right ) const
    { 
       return strcmp( sPtr, right.sPtr ) == 0; 
    } // end function operator==
    
    // Is this String less than right String?
    bool String::operator<( const String &right ) const
    { 
       return strcmp( sPtr, right.sPtr ) < 0; 
    } // end function operator<
    
    // return reference to character in String as a modifiable lvalue
    char &String::operator[]( int subscript )
    {
       // test for subscript out of range
       if ( subscript < 0 || subscript >= length )
       {
          cerr << "Error: Subscript " << subscript 
             << " out of range" << endl;
          exit( 1 ); // terminate program
       } // end if
    
       return sPtr[ subscript ]; // non-const return; modifiable lvalue
    } // end function operator[]
    
    // return reference to character in String as rvalue
    char String::operator[]( int subscript ) const
    {
       // test for subscript out of range
       if ( subscript < 0 || subscript >= length )
       {
          cerr << "Error: Subscript " << subscript 
               << " out of range" << endl;
          exit( 1 ); // terminate program
       } // end if
    
       return sPtr[ subscript ]; // returns copy of this element
    } // end function operator[]
    
    // return a substring beginning at index and of length subLength
    String String::operator()( int index, int subLength ) const
    {
       // if index is out of range or substring length < 0, 
       // return an empty String object
       if ( index < 0 || index >= length || subLength < 0 )  
          return ""; // converted to a String object automatically
    
       // determine length of substring
       int len;
    
       if ( ( subLength == 0 ) || ( index + subLength > length ) )
          len = length - index;
       else
          len = subLength;
    
       // allocate temporary array for substring and 
       // terminating null character
       char *tempPtr = new char[ len + 1 ];
    
       // copy substring into char array and terminate string
       strncpy( tempPtr, &sPtr[ index ], len );
       tempPtr[ len ] = '';
    
       // create temporary String object containing the substring
       String tempString( tempPtr );
       delete [] tempPtr; // delete temporary array
       return tempString; // return copy of the temporary String
    } // end function operator()
    
    // return string length
    int String::getLength() const 
    { 
       return length; 
    } // end function getLength
    
    // utility function called by constructors and operator=
    void String::setString( const char *string2 )
    {
       sPtr = new char[ length + 1 ]; // allocate memory
    
       if ( string2 != 0 ) // if string2 is not null pointer, copy contents
          strcpy( sPtr, string2 ); // copy literal to object
       else // if string2 is a null pointer, make this an empty string
          sPtr[ 0 ] = ''; // empty string
    } // end function setString 
    
    // overloaded output operator
    ostream &operator<<( ostream &output, const String &s )
    {
       output << s.sPtr;
       return output; // enables cascading
    } // end function operator<<
    
    // overloaded input operator
    istream &operator>>( istream &input, String &s )
    {
       char temp[ 100 ]; // buffer to store input
       input >> setw( 100 ) >> temp;
       s = temp; // use String class assignment operator
       return input; // enables cascading
    } // end function operator>>

    测试的源码:

    // String class test program.
    #include <iostream>
    using std::cout;
    using std::endl;
    using std::boolalpha;
    
    #include "String.h"
    
    int main()
    {
       String s1( "happy" );
       String s2( " birthday" );
       String s3;
    
       // test overloaded equality and relational operators
       cout << "s1 is "" << s1 << ""; s2 is "" << s2
          << ""; s3 is "" << s3 << '"' 
          << boolalpha << "
    
    The results of comparing s2 and s1:"
          << "
    s2 == s1 yields " << ( s2 == s1 )
          << "
    s2 != s1 yields " << ( s2 != s1 )
          << "
    s2 >  s1 yields " << ( s2 > s1 )
          << "
    s2 <  s1 yields " << ( s2 < s1 )
          << "
    s2 >= s1 yields " << ( s2 >= s1 )
          << "
    s2 <= s1 yields " << ( s2 <= s1 );
          
    
       // test overloaded String empty (!) operator
       cout << "
    
    Testing !s3:" << endl;
    
       if ( !s3 )
       {
          cout << "s3 is empty; assigning s1 to s3;" << endl;
          s3 = s1; // test overloaded assignment
          cout << "s3 is "" << s3 << """;
       } // end if
    
       // test overloaded String concatenation operator
       cout << "
    
    s1 += s2 yields s1 = ";
       s1 += s2; // test overloaded concatenation
       cout << s1;
    
       // test conversion constructor
       cout << "
    
    s1 += " to you" yields" << endl;
       s1 += " to you"; // test conversion constructor
       cout << "s1 = " << s1 << "
    
    ";
    
       // test overloaded function call operator () for substring
       cout << "The substring of s1 starting at
    "
          << "location 0 for 14 characters, s1(0, 14), is:
    "
          << s1( 0, 14 ) << "
    
    ";
    
       // test substring "to-end-of-String" option
       cout << "The substring of s1 starting at
    "
          << "location 15, s1(15), is: "
          << s1( 15 ) << "
    
    "; 
    
       // test copy constructor
       String *s4Ptr = new String( s1 );  
       cout << "
    *s4Ptr = " << *s4Ptr << "
    
    ";
    
       // test assignment (=) operator with self-assignment
       cout << "assigning *s4Ptr to *s4Ptr" << endl;
       *s4Ptr = *s4Ptr; // test overloaded assignment
       cout << "*s4Ptr = " << *s4Ptr << endl;
    
       // test destructor
       delete s4Ptr;     
    
       // test using subscript operator to create a modifiable lvalue
       s1[ 0 ] = 'H';      
       s1[ 6 ] = 'B';
       cout << "
    s1 after s1[0] = 'H' and s1[6] = 'B' is: "
          << s1 << "
    
    ";
    
       // test subscript out of range
       cout << "Attempt to assign 'd' to s1[30] yields:" << endl;
       s1[ 30 ] = 'd'; // ERROR: subscript out of range
       return 0;
    } // end main
  • 相关阅读:
    Django: ModelForm中Meta的fields等成员介绍
    python的random函数
    设置mysql隔离级别
    ubantu 下 修改mysql 默认编码
    jdbc 模板 连接
    sql 注入 与解决
    jdbc 简单连接
    动态代理 例子
    自定义的一个数据输入类
    类加载器 读取配置文件
  • 原文地址:https://www.cnblogs.com/graph/p/3345720.html
Copyright © 2011-2022 走看看