安定针作用:一个比较全的string类的实现

来源:百度文库 编辑:中财网 时间:2024/04/28 09:52:44
// MyString.h
// Definition of the MyString class representing strings
#ifndef MYSTRING_H
#define MYSTRING_H
namespace Louis {
    class MyString {
    public:
        MyString();                            // Default constructor
        MyString(const char* pString);        // Construct from a C-style string
        MyString(char ch, int n);            // Construct from repeated character
        MyString(int number);                // Construct string representation of integer
        MyString(const MyString& rString);    // Copy constructor
        ~MyString();                        // Destructor

        int length() const{ return strLength; }  // Return length excluding terminating null
        int find(char ch) const;                // Find the occurrence of a character
        int find(const char* pString) const;    // Find the occurrence of C-style string
        int find(const MyString& rString) const;// Find the occurrence of a MyString as a sub-string
        void show() const;                        // Output the string

        MyString& operator=(const MyString& str);    // Overloaded assignment operator

        MyString operator+(const MyString& str) const;    // string concatenation
        MyString& operator+=(const MyString& rStr);        // Append MyString
        MyString& operator+=(const char* rStr);            // Append C-Style string

        const char& operator[](int index) const;        // subscript operator for const objects
        char& operator[](int index);                    // subscript operator for non-const objects

        // Comparison operators all return type bool
        bool operator==(const MyString& rStr) const;
        bool operator!=(const MyString& rStr) const;
        bool operator<(const MyString& rStr) const;
        bool operator>(const MyString& rStr) const;

        // Return an object corresponding to a substring
        MyString operator()(int index, int length) const;

    private:
        size_t strLength;
        char* pStr;
    };
} // End of namespace Louis
#endif

 


 // MyString.cpp
// Definitions for member of the MyString class

#include "MyString.h"
#include 
#include 
#include 
using std::cout;
using std::endl;

namespace Louis {

    // Default constructor
    MyString::MyString() {
        strLength = 0;        // Length excludes terminating null - this is empty string
        pStr = new char[1]; // Allocate space for string in the free store
        *pStr = '\0';       // Store terminating null
    }

    // Construct from a C-style string
    MyString::MyString(const char* pString) {
        strLength = strlen(pString);    // strlen() returns length excluding terinating null
        pStr = new char[strLength+1];    // Space must allow for null, hence strLength+1
        strcpy(pStr, pString);            // Copy argument string to data member
    }

    // Construct from repeated character
    MyString::MyString(char ch, int n) {
        strLength = n;
        pStr = new char[strLength+1];
        for (unsigned int i=0; i            ;                                                 // No loop statement
        *(pStr+strLength) = '\0';        // Store terminating null
    }

    // Construct string representation of integer
    MyString::MyString(int number) {
        char buffer[20];            // Buffer to store string representation
        int temp = number;
        if (number<0)                // If it is negative.
            number = -number;        // reverse the sign

        // Convert digits to characters in reverse order
        int len = 0;
        do {
            buffer[len++] = static_cast('0' + number%10);
            number /= 10;
        }while(number>0);

        if (temp<0)                    // If it was negative
            buffer[len++] = '-';    // Append a minus sign
        buffer[len] = '\0';            // Append terminal \0

        strLength = len;            // Store length of string

        pStr = new char[strLength+1];    // Allocate space
        strcpy(pStr, buffer);        // Copy string to data member

        // String is reversed so reverse it in place
        char ch = 0;
        for (int i=0, j=len-1; i            ch = pStr[i];
            pStr[i] = pStr[j];
            pStr[j] = ch;
        }
    }

    // Copy constructor
    // Needs to allocate space for a copy of the string, then copy it
    MyString::MyString(const MyString& rString) {
        strLength = rString.strLength;        // Store the length
        pStr = new char[strLength+1];        // Allocate the required space
        strcpy(pStr, rString.pStr);            // Copy the string
    }

    // Destructor
    // releases free store memory allocated to store string
    MyString::~MyString() {
        //std::cout << "Destructor called." << std::endl;
        delete[] pStr;        // Must use array form of delete here
    }


    // Find the position of a character
    // Compares succesive characters in the satring with the argument
    int MyString::find(char ch) const {
        for (unsigned int i=0; i            if (ch == *(pStr+i))        // If we find the character,
                return i;                // return its position,
        return -1;                        // otherwise return -1
    }

    // Find the position of a string
    // Searches for the first character of the substring
    // and looks for the remaining characters if it is found
    int MyString::find(const char* pString) const {
        bool found = false;            // Sub-string found indicator

        // Search for the sub-string. We only need to look for 
        // the first character up to the position where there is 
        // enough room left for the sub-string to appear.
        for (unsigned int i=0; i            if (*(pStr+i) == *pString) {    // If we find the first charcter
                found = true;
                for (unsigned int j=1; j                    if (*(pStr+i+j) != *(pString+j)) {  // If any character doesn't match,
                        found = false;                    // we didn't find it
                        break;                            // so go to next iteration in outer loop
                    }
                if (found)            // If we found it,
                    return i;        // Return the position,
            }
        return -1;                    // otherwise return -1
    }

    // Find the occurrence of a MyString as a sub-string
    int MyString::find(const MyString& rString) const {
        return find(rString.pStr);    // Just use the previous function to do it
    }

    // Display the string
    void MyString::show() const {
        if (strLength)
            cout << endl << pStr;
        else
            cout << endl << "String is empty.";
    }

    // Overloaded assignment operator
    MyString& MyString::operator =(const MyString& rStr) {
        if (this == &rStr)    // Is left string same object as right string?
            return *this;    // Yes, so just return it.

        // object are different so assign rStr to *this
        delete[] pStr;    //Release memory for left operand (current string for *this object)
        strLength = strlen(rStr.pStr);        // strlen() returns length excluding terinating null
        pStr = new char[strLength+1];    // Allocate space for string to be copied, space must allow for null, hence strLength+1
        strcpy(pStr, rStr.pStr);        // Copy argument string to data member

        return *this;
    }

    // String concatenation
    // Operator must return a new object which is created as a local object
    // A copy of the local object will be returned
    MyString MyString::operator+(const MyString& rStr) const {
        return MyString(*this) += rStr;
    }

    // Append MyString string
    // Operator returns a reference to the left string
    // Uses the += operator for C-style strings to append the right string
    MyString& MyString::operator+=(const MyString& rStr) {
        return *this += rStr.pStr;
    }

    // Append C-style string
    MyString& MyString::operator+=(const char* rStr) {
        char* pNewStr = new char[strLength + strlen(rStr) + 1];    // Space for combined string
        strcpy(pNewStr, pStr);                                    // Copy left string to new string
        strcpy(pNewStr+strLength, rStr);                        // Append right string to new string
        strLength = strlen(pNewStr);                            // Update length
        delete[] pStr;                                            // Release left string memory
        pStr = pNewStr;                                            // Left string is new string
        return *this;                                            // Return left string
    }

    // subscript operator for const objects
    // cannot be used on the left of an assignment as it return a const reference to char
    const char& MyString::operator [](int index) const {
        // There validity check would be better using exceptions to signal errors
        // rather than calling exit(). 
        if (strLength == 0) {
            cout << "\nString is empty in subscript operation. Program aborted.";
            exit(1);
        }
        if (strLength < index || index < 0) {
            cout << "\nOut of range index in subscript operation. Program aborted.";
            exit(1);
        }

        if (index < strLength)
            return pStr[index];
        exit(1);
    }

    // subscript operator for non-const objects - can be used on the left of an assignment
    char& MyString::operator [](int index) {
        // These validity check would be better using exceptions to signal errors
        // rather than calling exit().
        if (strLength == 0) {
            cout << "\nString is empty in subscript operation. Program aborted.";
            exit(1);
        }
        if (strLength < index || index < 0) {
            cout << "\nOut of range index in subscript operation. Program aborted.";
            exit(1);
        }

        if (index < strLength)
            return pStr[index];
        exit(1);
    }

    // Overloaded 'equals' operator
    bool MyString::operator ==(const MyString& rStr) const {
        return strcmp(pStr, rStr.pStr) == 0;
    }

    // Overloaded 'not equals' operator
    bool MyString::operator !=(const MyString& rStr) const {
        return !(*this == rStr);
    }

    // Overloaded 'greater than' operator
    bool MyString::operator >(const MyString& rStr) const {
        return strcmp(pStr, rStr.pStr) > 0;
    }

    // Overloaded 'less than' operator
    bool MyString::operator <(const MyString& rStr) const {
        return strcmp(pStr, rStr.pStr) < 0;
    }

    // Overloaded function call operator
    // Returns a substring object - not a reference.
    // A copy of the local object will be returned.
    MyString MyString::operator ()(int index, int length) const {
        if (index < 0 || index > strLength || index + length > strLength) {
            cout << "\nOut of range in function call operator. Terminating program.";
            exit(1);
        }

        char* pSubStr = new char[length+1];    // Get space for substring

        for (int i=0; i            pSubStr[i] = pStr[index+i];
        
        pSubStr[length] = '\0';                // Append null character for end
        
        MyString tempStr(pSubStr);        // Define a new object    
        delete[] pSubStr;                // Delete temporary string
        return tempStr;                    // Return the object
    }


}  // End of namespace mySapce
  // main.cpp
#include 
using std::cout;
using std::endl;

#include "MyString.h"

using namespace Louis;

void main() {
    MyString s1;
    MyString s2("s2: aaaaa");
    MyString s3("s3: ccccc");

    MyString s4;
    s4 = s2 + s3;

    s1 = s2;
    s1 = s1;
    s1 = s2 = s3;

    s1.show();
    s2.show();
    s3.show();
    s4.show();

    s2 += s3;
    s2.show();

    s2 += " hello";
    s2.show();
    cout << endl;

    cout << s2[s2.length()-1];
    cout << endl;

    s2[s2.length()-1] = 'x';
    cout << s2[s2.length()-1];
    cout << endl;


    MyString str1("aaaa");
    MyString str2("aaaa");
    MyString str3("bbbb");
    MyString str4("cccc hello world");

    if (str1==str2) 
        cout << "str1 equal str2." << endl;

    if (str1 != str3)
        cout << "str1 not equal str3." << endl;

    if (str1 < str3)
        cout << "str1 < str3" << endl;

    if (str4 > str3)
        cout << "str4 > str3" << endl;

    MyString str5 = str4(5,5);
    str5.show();
    cout << endl;
}