MyString類的實現

    string類在c++中使得程序員對於字符串的操作更加方便,今天就來編寫自己的MyString類。

   先來看mystring.h的定義:

#ifndef _MYSTRING_H_
#define _MYSTRING_H_

#include<iostream>
using namespace std;

class MyString{
public:
    MyString();
    MyString(const char* str);
    MyString(const size_t len,const char ch);
    MyString(const MyString& t);
    ~MyString();
public:
    //屬性
    size_t length();
    bool empty();
    const char* c_str();    //返回C風格字符串指針
    //讀寫操作
    friend ostream& operator<< (ostream& out,const MyString& str);
    friend istream& operator>> (istream& in, MyString& str);
    //'+'操作
    friend MyString operator+ (const MyString& str1,const MyString& str2);
    //比較操作
    friend bool operator== (const MyString& str1,const MyString& str2);
    friend bool operator!= (const MyString& str1,const MyString& str2);
    friend bool operator< (const MyString& str1,const MyString& str2);
    friend bool operator<= (const MyString& str1,const MyString& str2);
    friend bool operator> (const MyString& str1,const MyString& str2);
    friend bool operator>= (const MyString& str1,const MyString& str2);

    //下標操作
    char& operator[] (const size_t);
    const char& operator[] (const size_t)const;
    //賦值操作
    MyString& operator= (const MyString& str);
    //'+='操作
    MyString& operator+= (const MyString& str);
    //子串操作
    MyString substr(size_t,size_t);
    //添加操作
    MyString& append(const MyString& str);
    //插入操作
    MyString& insert(size_t,const MyString&);
    //替換操作
    MyString& assign(const MyString&,size_t,size_t);
    //刪除操作
    MyString& erase(size_t,size_t);
private:
    char *base;
    size_t strlength;
};

#endif

接下來來看具體的實現:

#include<iostream>
#include<string>
#include<string.h>
#include<assert.h>
#include"mystring.h"

MyString::MyString()
{
    base = NULL;
    strlength = 0;
}
MyString::MyString(const char* str)
{
    if(str == NULL){
        return ;
    }
    strlength = strlen(str);
    base = new char[strlength + 1];
    strcpy(base,str);    
}
MyString::MyString(size_t len,const char ch)
{
    strlength = len;
    base = new char[strlength + 1];
    base[strlength + 1] = '\0';
    for(int i = 0;i< strlength;++i){
        base[i] = ch;
    }
}
MyString::MyString(const MyString& t)
{
    this->strlength = t.strlength;
    base = new char[strlength + 1];
    strcpy(base,t.base);
}
MyString::~MyString()
{
    delete []base;
}
size_t MyString::length()
{
    return strlength;
}
bool MyString::empty()
{
    return strlength == 0 ? true : false;
}

const char* MyString:: c_str()    //返回C風格字符串指針
{
    return base;
}
//下標操作
char& MyString::operator[] (const size_t index)
{
    assert(index >=0 && index <= strlength);
    return base[index];
}
const char& MyString::operator[] (const size_t index)const
{
    assert(index >=0 && index <= strlength);
    return base[index];
}
//賦值操作
MyString& MyString::operator= (const MyString& str)
{
    if(this != &str){
        delete []base;
        base = new char[str.strlength + 1];
        strlength = str.strlength ;
        strcpy(base,str.base);       
    }
    return *this;
}
//'+='操作
MyString& MyString::operator+= (const MyString& str)
{
    if(this != &str){
        strlength += str.strlength;
        char *p_str;
        p_str = new char[strlength + 1];
        strcpy(p_str,base);
        delete []base;
        strcat(p_str,str.base);
        base = p_str;
        return *this;
    }
    MyString copy(str);
    return *this += copy;
}
//子串操作
//返回一個MyString 類型的字符串,它包含源字符串中從下標pos開始的n個字符
MyString MyString::substr(size_t pos,size_t n)
{
    assert(pos + n <= strlength);
    MyString ret;
    ret.strlength = n;
    ret.base = new char[ret.strlength + 1];
    for(size_t i = 0;i < n;++i){
        ret[i] = base[pos + i];
    }
    ret[ret.strlength] = '\0';
    return ret;
}
//添加操作
//將一個字符串的副本添加源字符串的末尾,同"+="操作符類似
MyString& MyString::append(const MyString& str)
{
    *this += str;
    return *this;
}
//插入操作
//在下標pos的元素之前插入MyString對象str的副本
MyString& MyString::insert(size_t pos,const MyString& str)
{
    assert(pos < strlength);
    int len = str.strlength;
    int len1 = strlength ;
    char *p_str;
    int i;
    strlength += str.strlength;
    p_str  = new char[strlength + 1];
    for(i = 0; i < pos;++i){
        p_str[i] = base[i];
    }
    for(int j = 0 ; j < str.strlength;++j){
        p_str[i++] = str[j];
    }
    for(int k = pos ; k <= len1;++k){
        p_str[i++] = base[k];
    }
    p_str[strlength] = '\0';
    delete []base;
    base = p_str;
    return *this;
}
//替換操作
//用s2中下標pos開始的len個字符副本替換源字符串
MyString& MyString::assign(const MyString& s2,size_t pos,size_t len)
{
    if(strlength < len){
        char* p_str = new char[len + 1];
        strlength = len;
        delete []base;
        base = p_str;
    }
    int i;
    for(i = 0;i < len;++i){
        base[i] = s2[i];
    }
    base[strlength] = '\0';
    return *this;
}
//刪除操作
//刪除從下標pos開始的len的字符
MyString& MyString::erase(size_t pos,size_t len)
{
    assert(pos + len <= strlength);
    for(int i = pos ,j = pos + len ; i < pos + len && j <= strlength ; ++i,++j){
        base[i] = base[j];
    }
    strlength -= len;
    base[strlength] = '\0';
    return *this;
}

//讀寫操作
ostream& operator<<(ostream& out,const MyString& t)
{
    if(t.base != NULL){
        cout << t.base;
    }
    return out;
}
istream& operator>> (istream& in, MyString& str)
{
    char tmp[100];
    if(in >> tmp){
        delete []str.base;
        str.strlength = strlen(tmp);
        str.base = new char[str.strlength + 1];
        strcpy(str.base,tmp);
    }
    return in;
}
//'+'操作
MyString operator+ (const MyString& str1,const MyString& str2)
{
    MyString ret;
    ret.strlength = str1.strlength + str2.strlength ;
    ret.base = new char[ret.strlength + 1];
    strcpy(ret.base,str1.base);
    strcat(ret.base,str2.base);
    return ret;
}
//比較操作
bool operator== (const MyString& str1,const MyString& str2)
{
    return strcmp(str1.base , str2.base) == 0;
}
bool operator!= (const MyString& str1,const MyString& str2)
{
    return strcmp(str1.base , str2.base) != 0;
}
bool operator< (const MyString& str1,const MyString& str2)
{
    return strcmp(str1.base , str2.base) < 0;
}
bool operator<= (const MyString& str1,const MyString& str2)
{
    return strcmp(str1.base , str2.base) <= 0;
}
bool operator> (const MyString& str1,const MyString& str2)
{
    return strcmp(str1.base , str2.base) > 0;
}
bool operator>= (const MyString& str1,const MyString& str2)
{
    return strcmp(str1.base , str2.base) >= 0;
}

測試程序:

#include<iostream>
#include<string>
#include"mystring.h"
#include<string.h>
using namespace std;
int main(int argc,char**argv)
{
    MyString s;
    MyString s1("hello");
    MyString s2(10,'h');
    MyString s3 = s1;
    MyString s4("world");
    MyString s5(10,'e');
    MyString s6("family");
    const char *str = s.c_str();
    const char *str1 = s1.c_str();
    const char *str2 = s2.c_str();
    const char *str3 = s3.c_str();
    #if 1
    cout << s <<endl;
    cout << "s length : " << s.length() << endl;
    if(s.empty()){
        cout << "s is empty!"<<endl;
    }else{
        cout << "s is not empty!!" << endl;
    }

    cout << s1 <<endl;
    cout << "s1 length : " << s1.length() << endl;
    if(s1.empty()){
        cout << "s1 is empty!"<<endl;
    }else{
        cout << "s1 is not empty!!" << endl;
    }

    cout << s2 <<endl;
    cout << "s2 length : " << s2.length() << endl;
    if(s2.empty()){
        cout << "s2 is empty!"<<endl;
    }else{
        cout << "s2 is not empty!!" << endl;
    }

    cout << s3 <<endl;
    cout << "s3 length : " << s3.length() << endl;
    if(s3.empty()){
        cout << "s3 is empty!"<<endl;
    }else{
        cout << "s3 is not empty!!" << endl;
    }

   //cout << "s c_str(): " << str << endl;
   cout << "s1 c_str(): " << str1 << endl;
   cout << "s2 c_str(): " << str2 << endl;
   cout << "s3 c_str(): " << str3 << endl;

    cout << "s1[] :" << endl;
    for(int i = 0;i <= s1.length() ;++i){
        cout << s1[i] << " ";
    }
    cout << endl;

    cout << "s2[] :" << endl;
    for(int i = 0;i <= s2.length() ;++i){
        cout << s2[i] << " ";
    }
    cout << endl;

    cout << "s3[] :" << endl;
    for(int i = 0;i <= s3.length() ;++i){
        cout << s3[i] << " ";
    }
    cout << endl;
   
    s3 = s2;
    cout << "s3 = s2 : " << endl;
    cout << "s3 : "<< s3 << endl;
    
    s1 += s4;
    cout << "s1 += s4 : " << s1 << endl;
    s1 += s1;
    cout << "s1 += s1 : " << s1 << endl;

    s2 += s1;
    cout << "s2 += s1 : " << s2 << endl;
    s2 += s2;
    cout << "s2 += s2 : " << s2 << endl;
    #endif
    s = s1.substr(0,4);
    cout << "s1.substr(): " << s << endl;
    
    #if 1
    s4 = s1.append(s4);
    cout <<"s1: " << s1 <<endl;
    cout <<"s4: " << s4 <<endl;
    
    
    cout << "s4 : " << s4 << endl;
    cout << "s5 : " << s5 << endl;
    s4.insert(1,s5);
    cout << "s4 (befor 1)insert s5 :    " << endl ;
    cout << "s4 : " << s4 << endl;
    cout << endl;


    cout << "s5 : " << s5 << endl;
    cout << "s6 : " << s6 << endl;
    s6.insert(1,s5);
    cout << "s6 (befor 1) insert s5 :    " << endl ;
    cout << "s5 : " << s5 << endl;
    cout << "s6 : " << s6 << endl;
    cout << endl;

    #endif
    #if 1
    cout << "s2 : " << s2 << endl;
    cout << "s6 : " << s6 << endl;
    s6.assign(s2,0,10);
    cout << "s2 (0,10) assgin s6:    " << endl ;
    cout << "s2 : " << s2 << endl;
    cout << "s6 : " << s6 << endl;
    cout << endl;

    
    cout << "s2 : " << s2 << endl;
    cout << "s6 : " << s6 << endl;
    s6.assign(s2,0,20);
    cout << "s2 (0,20) assgin s6:    " << endl ;
    cout << "s2 : " << s2 << endl;
    cout << "s6 : " << s6 << endl;
    cout << "s5 :" << endl;
    cout << s5 << endl;
    cout << "s6 :" << endl;
    cout << s6 << endl;

    cout << "s6 : " <<endl;
    cout << s6 << endl;
    s6.erase(1,15);
    cout << "s6 erase : " <<endl;
    cout << s6 << endl;
   
    cout << "s5 :" << endl;
    cout << s5 << endl;
    cout << "s6 :" << endl;
    cout << s6 << endl;
    s6 = s5 + s6;
    cout << "s6  = s5 + s6 " << endl;
    cout << s6 << endl;
  
    cout << endl;
 
    cout << "s5 :" << endl;
    cout << s5 << endl;
    cout << "s6 :" << endl;
    cout << s6 << endl;
    if(s5 > s6){
        cout << "s5 > s6 " << endl;
    }

    if(s5 >= s6){
        cout << "s5 >= s6 " << endl;
    }

    if(s5 == s6){
        cout << "s5 == s6 " << endl;
    }

    if(s5 != s6){
        cout << "s5 != s6 " << endl;
    }

    if(s5 < s6){
        cout << "s5 < s6 " << endl;
    }

    if(s5 <= s6){
        cout << "s5 <= s6 " << endl;
    }
    #endif
    return 0;
}

部分執行結果:

通過string類的編寫更加深刻體會到c++的面向對象的特點,之後還會繼續對繼承和多態,甚至設計模式都會有比較深的理解的。。。

發佈了65 篇原創文章 · 獲贊 19 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章