国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

php購物網站搜索欄怎么做怎么樣把廣告做在百度上

php購物網站搜索欄怎么做,怎么樣把廣告做在百度上,西安公司建一個網站需要多少錢,做電影網站用什么空間?感謝您閱讀本篇文章,文章內容是個人學習筆記的整理,如果哪里有誤的話還請您指正噢? ? 個人主頁:余輝zmh–CSDN博客 ?文章所屬專欄:c篇–CSDN博客 文章目錄 前言一.string類的默認成員函數(shù)以及深拷貝1.基本框架2.默認成員函數(shù)…

?感謝您閱讀本篇文章,文章內容是個人學習筆記的整理,如果哪里有誤的話還請您指正噢?
? 個人主頁:余輝zmh–CSDN博客
?文章所屬專欄:c++篇–CSDN博客

在這里插入圖片描述

文章目錄

  • 前言
  • 一.`string`類的默認成員函數(shù)以及深拷貝
    • 1.基本框架
    • 2.默認成員函數(shù)
      • 1.構造函數(shù)
      • 2.析構函數(shù)
      • 3.拷貝構造函數(shù)(深拷貝)
      • 4.賦值運算符重載(深拷貝)
    • 3.什么是深拷貝
      • 深拷貝的必要性
      • 深拷貝的實現(xiàn)
    • 4.測試
  • 二.`string`類的訪問和迭代器相關函數(shù)
    • 1.訪問相關函數(shù)
    • 2.迭代器相關函數(shù)
      • 1.普通`string`對象的迭代器
      • 2.`const` `string`對象的迭代器
    • 3.測試
  • 三.`string`類的容量相關函數(shù)
    • 1.容量大小相關函數(shù)
    • 2.擴容相關函數(shù)
    • 3.測試
  • 四.`string`類的修改相關函數(shù)
    • 1.拼接操作相關函數(shù)
    • 2.插入操作相關函數(shù)
    • 3.刪除操作相關函數(shù)
    • 4.測試
  • 五.`string`類的流插入和流提取函數(shù)
  • 六.`string`類完整代碼
    • 1.`string.h`頭文件代碼
    • 2.`string.cpp`函數(shù)定義文件代碼
    • 3.`test.cpp`測試文件代碼

前言

在上一篇文章中,我們了解到了std::string類的常用接口函數(shù)以及如何熟練使用。在這片文章中,我們將深入探討如何模擬實現(xiàn)一個基本的string類。我們的目的不是創(chuàng)建一個功能完整的string庫,而是通過這個過程來學習字符串處理的基本原理和常見的實現(xiàn)技巧。通過模擬實現(xiàn)string類,我們不僅能夠深入理解字符串的內部工作原理,還能鍛煉我們的編程能力,提高解決問題的能力,希望這篇文章能過為你的編程之旅提供有價值的參考和啟發(fā)。

注意:模擬實現(xiàn)string類需要用到三個文件

  • test.cpp文件用來進行測試
  • string.cpp文件用來定義接口函數(shù)(部分較為短小的函數(shù)將會直接在string.h文件中定義)
  • string.h文件用來聲明頭文件和string類

一.string類的默認成員函數(shù)以及深拷貝

1.基本框架

為了和庫里面的std::string類進行區(qū)分,我們首先定義一個命名空間Mystring用來封裝我們自己模擬實現(xiàn)的string類。

基本框架如下:

namespace Mystring{class string{Public:static const size_t npos=-1;//成員函數(shù)private://成員變量char* _str;size_t _size;size_t capacity;};
}
  • _str在堆上開辟動態(tài)內存用來存儲string對象的數(shù)據(jù)。
  • _size用來記錄string對象的實際大小。
  • _capacity用來記錄當前string對象可存儲的最大容量。
  • npos是一個無符號整形的最大值,在查找等相關函數(shù)會用到。

2.默認成員函數(shù)

前面我們知道,一個類中有六個默認成員函數(shù)(在我之前的文章類和對象(二)中有關于默認成員函數(shù)的詳細講解,不清楚的可以看我之前的文章),在模擬實現(xiàn)string類時,我們只需要實現(xiàn)常用的四個(構造函數(shù),析構函數(shù),拷貝構造函數(shù),賦值運算符重載)即可。

1.構造函數(shù)

  • 代碼實現(xiàn):

    //string.h中聲明
    string(const char* str = "");
    //string.cpp中定義
    Mystring::string::string(const char* str)
    :_size(strlen(str))
    ,_capacity(_size)
    ,_str(new char[_size+1])
    {memcpy(_str,str,_size+1);
    }
    
  • 實現(xiàn)原理:

    • str字符串作為常量參數(shù)用來創(chuàng)建string對象,缺省值為空字符串(當沒有參數(shù)時就是創(chuàng)建一個空對象),缺省值要在聲明中給,不能再定義中給。
    • _size字符串大小和_capacity容量初始化值為參數(shù)str字符串的大小(strlen(str))。
    • _str指針用來指向存儲string對象的動態(tài)內存,開辟空間的大小為參數(shù)str字符串的大小加一,加一是為了存放結尾的’\0’,開辟空間后要將str字符串內容拷貝到開辟的動態(tài)內存。

2.析構函數(shù)

  • 代碼實現(xiàn):

    //string.h文件中聲明
    ~string();
    //string.cpp文件中定義
    Mystring::string::~string(){delete[] _str;_str=nullptr;_size=0;_capacity=0;
    }
    
  • 實現(xiàn)原理:

    • 釋放動態(tài)內存空間,再將_str指針置為空指針。
    • _size字符串大小和_capacity容量置為0。

3.拷貝構造函數(shù)(深拷貝)

  • 代碼實現(xiàn):

    //string.h文件中聲明
    string(const string&s);
    //string.cpp文件中定義
    Mystring::string::string(const string&s)
    {_str=new char[s._capacity+1];strcpy(_str,s._str);_size=s._size;_capacity=s._capacity;
    }
    
  • 實現(xiàn)原理:

    • 用一個string對象拷貝構造一個新的string對象,拷貝構造函數(shù)需要完成深拷貝。
    • 先用字符串s的容量作為新空間的大小申請一個新的動態(tài)內存空間,再將s字符串的數(shù)據(jù)拷貝到新的內存空間中。
    • 新的string對象的_size和_capacity分別是原string對象的_size和_capacity.

4.賦值運算符重載(深拷貝)

  • 代碼實現(xiàn):

    //string.h文件中聲明
    string& operator=(const string&s);
    //string.cpp文件中定義
    Mystring::string& Mystring::string::operator=(const string&s)
    {char* tmp=new char[s._capacity+1];memcpy(tmp,s._str,s._size+1);delete[] _str;_str=tmp;_capacity=s._capacity;_size=s._size;return *this;
    }
    
  • 實現(xiàn)原理:

    • 賦值和拷貝構造的不同點在于,拷貝構造是用已有的對象拷貝構造一個新的對象;而賦值是用一個已存在的對象賦值給另一個已存在的對象,賦值也是需要完成深拷貝。
    • 先用賦值對象s的容量大小申請一個新的動態(tài)內存空間,設置一個新的tmp指針先指向這塊空間,再將賦值對象s的數(shù)據(jù)拷貝到新的內存空間中。
    • 釋放被賦值對象的原有空間,再將被賦值對象的_str指針指向新的內存空間。
    • 被賦值對象的_size和_capacity分別是賦值對象s的_size和_capacity.

3.什么是深拷貝

深拷貝(Deep Copy)是對象復制操作中的一種,它不僅僅復制對象的表層數(shù)據(jù)(如指針或引用),還會遞歸地復制對象內部所有動態(tài)分配的內存、引用的其他對象或其他資源。這樣,復制出來的新對象與原始對象在內存中是完全獨立的,對它們的修改不會影響到彼此。

深拷貝的必要性

當對象包含指向動態(tài)分配內存的指針或其他需要管理的資源時,淺拷貝(僅復制指針值)會導致兩個對象共享同一塊內存。這可能會引發(fā)以下問題:

  1. 數(shù)據(jù)損壞:一個對象修改了它共享的內存中的數(shù)據(jù),導致另一個對象看到的數(shù)據(jù)也發(fā)生了變化。
  2. 內存泄漏:如果兩個對象都認為自己擁有這塊內存,并在析構時嘗試釋放它,就會導致重復釋放內存的錯誤(double free),進而可能導致程序崩潰。
  3. 資源管理混亂:如果對象還管理其他資源(如文件句柄、網絡連接等),共享這些資源可能會導致資源被意外關閉或重復訪問。

深拷貝的實現(xiàn)

實現(xiàn)深拷貝通常涉及以下幾個步驟:

  1. 為新對象分配內存:如果原始對象包含動態(tài)分配的內存,深拷貝的第一步是為新對象分配相應的內存空間。
  2. 復制數(shù)據(jù):將原始對象中的數(shù)據(jù)復制到新分配的內存中。如果數(shù)據(jù)本身也是對象(即對象包含指向其他對象的指針),則需要遞歸地應用深拷貝。
  3. 更新指針:將新對象的指針成員指向新分配的內存,而不是原始對象的內存。
  4. 處理其他資源:如果對象管理其他資源(如文件、網絡連接等),則需要確保新對象也能正確地獲取或創(chuàng)建這些資源的副本。

4.測試

測試代碼如下:

void test1(){//創(chuàng)建s1對象Mystring::string s1("hello world");//用s1對象拷貝構造s2對象Mystring::string s2(s1);//將s1對象賦值給s3對象Mystring::string s3("hello");s3=s1;
}

測試結果如下:

在這里插入圖片描述

二.string類的訪問和迭代器相關函數(shù)

1.訪問相關函數(shù)

  • at()函數(shù)代碼實現(xiàn):

    //string文件中聲明和定義
    char& at(size_t pos)
    {//斷言檢查pos是否符合字符串的范圍assert(pos<_size);//直接返回字符數(shù)組對應下標上的字符即可return _str[pos];
    }
    
  • operator[]函數(shù)代碼實現(xiàn):

    //string文件中聲明和定義
    //和at()函數(shù)同理
    char& operator[](size_t pos)
    {assert(pos<_size);return _str[pos];
    }
    

2.迭代器相關函數(shù)

1.普通string對象的迭代器

  • 類型定義:

    //普通string對象的迭代器類型
    typedef char* iterator;
    
  • begin()函數(shù)代碼實現(xiàn):

    //string文件中聲明和定義
    iterator begin()const
    {//返回_str首元素的地址return _str;
    }
    
  • end()函數(shù)代碼實現(xiàn):

    //string文件中聲明和定義
    iterator end()const
    {//返回_str最后一個元素的下一個位置的地址return _str+_size;
    }
    

2.const string對象的迭代器

  • 類型定義:

    //const string對象的迭代器類型
    typedef const char* const_iterator;
    
  • cbegin()函數(shù)代碼實現(xiàn):

    //string文件中聲明和定義
    const_iterator begin()const
    {//返回_str首元素的地址return _str;
    }
    
  • cend()函數(shù)代碼實現(xiàn):

    //string文件中聲明和定義
    const_iterator end()const
    {//返回_str最后一個元素的下一個位置的地址return _str+_size;
    }
    

3.測試

測試代碼如下:

void test2(){Mystring::string s1("hello world");//使用opreator[]打印s1for(size_t i=0;i<s1.size();i++){cout<<s1[i]<<" ";}cout<<endl;//使用普通對象的迭代器打印s1Mystring::string::iterator it=s1.begin();while(it!=s1.end()){cout<<*it<<" ";it++;}cout<<endl;//使用const對象的迭代器打印s2const Mystring::string s2("hello");Mystring::string::const_iterator rit=s2.begin();while(rit!=s2.end()){cout<<*rit<<" ";rit++;}cout<<endl;
}

測試結果如下:

在這里插入圖片描述

三.string類的容量相關函數(shù)

1.容量大小相關函數(shù)

獲取string對象的大小需要使用size()函數(shù),獲取容量則需要使用capacity()函數(shù)

  • size()函數(shù)代碼實現(xiàn):

    //string.h文件中聲明和定義
    //直接返回_size即可
    size_t size()
    {return _size;
    }
    
  • capacity()函數(shù)代碼實現(xiàn):

    //string.h文件中聲明和定義
    //直接返回_capacity即可
    size_t capacity()
    {return _capacity;
    }        

2.擴容相關函數(shù)

string類擴容相關的函數(shù)主要是reserve()resize()。

  • reserve()函數(shù)代碼實現(xiàn):

    //string.h文件中聲明
    void reserve(size_t);
    //string.cpp文件中定義
    void Mystring::string::reserve(size_t n)
    {if(n>_capacity){char*tmp=new char[n+1];memcpy(tmp,_str,_size+1);delete[] _str;_str=tmp;_capacity=n;}
    }
    
  • 實現(xiàn)原理:

    • 首先判斷需要擴容的大小n是否大于原容量大小_capacity,如果小于則不進行擴容,大于時就需要擴容。
    • 擴容時先開辟內存大小為(n+1)的動態(tài)內存空間,在設置一個新的字符指針tmp指向新的內存空間,然后將原string對象的數(shù)據(jù)拷貝到新的內存空間中。
    • 釋放原string對象的_str指針,再從新指向開辟的新內存空間,最后更改內存大小為n。
  • resize()函數(shù)代碼實現(xiàn):

    //string.h文件中聲明
    void resize(size_t n,char ch='\0');
    //string.cpp文件中定義
    void Mystring::string::resize(size_t n,char ch)
    {if(n>_capacity){reserve(n);}if(n>_size){for(size_t i=_size;i<n;i++){_str[i]=ch;}}_size=n;_str[_size]='\0';}
    
  • 實現(xiàn)原理:

    • 首先依然是需要判斷擴容的大小n是否大于原容量大小_capacity,和reserve()函數(shù)不同的是,resize對于擴容大小n小于原容量大小時會發(fā)生截斷,大于時就會進行擴容操作,這里擴容操作直接調用reserve()函數(shù)即可。

    • 如果擴容大小n大于原string對象的_size,需要將多余的空間初始化為參數(shù)ch,參數(shù)ch的缺省值設置為’\0’(要在聲明中給),沒有傳參時,默認初始化為0。

3.測試

測試代碼如下:

void test3(){Mystring::string s1("hello world");cout<<s1.size()<<" "<<s1.capacity()<<endl;//s1容量擴為15s1.reserve(15);cout<<s1.size()<<" "<<s1.capacity()<<endl;//s1容量擴為20,多余空間用字符a填充s1.resize(20,'a');cout<<s1.size()<<" "<<s1.capacity()<<endl;cout<<s1<<endl;//s1縮容為8,發(fā)生截斷s1.resize(8);cout<<s1.size()<<" "<<s1.capacity()<<endl;cout<<s1<<endl;
}

測設結果如下:

在這里插入圖片描述

四.string類的修改相關函數(shù)

1.拼接操作相關函數(shù)

  • 1.push_back()函數(shù)實現(xiàn):

    //string.h文件中聲明
    void push_back(char ch);
    //string.cpp文件中定義
    void Mystring::string::push_back(char ch)
    {if(_size==_capacity){reserve(_capacity==0?4:2*_capacity);}_str[_size]=ch;_size++;_str[_size]='\0';
    }
    

    2.實現(xiàn)原理:

    • push_back()函數(shù)的功能是尾插單個字符,在尾插之前要先判斷是否需要擴容,在擴容時,如果需要尾插的string對象是空對象擴容 大小先設置為4,如果不是空對象則擴容大小是原容量的二倍,擴容直接調用reserve()函數(shù)即可。
    • 插入時,將原來字符串的’\0’位置存放插入的字符ch,再將大小_size增加一,最后重新在字符串的結尾加上’\0’。
  • 1.append()函數(shù)實現(xiàn):

    append()函數(shù)有兩種不同的實現(xiàn),一個是在原string對象后增加單個字符,一個是增加字符串。

    //string.h文件中聲明
    void append(char ch);                
    void append(const char* str);  
    //string.cpp文件中定義
    //增加單個字符
    void Mystring::string::append(char ch)
    {push_back(ch);
    }
    //增加字符串
    void Mystring::string::append(const char* str)
    {size_t len=strlen(str);if(_size+len>_capacity){reserve(_size+len);}//_str加上_size就是原字符串結尾的位置,插入的字符串拷貝到原字符串后面memcpy(_str+_size,str,len+1);_size+=len;
    }
    

    2.實現(xiàn)原理:

    • 增加單個字符直接調用push_back函數(shù)。
    • 增加字符串時,先獲取插入字符串的大小len,然后判斷原字符串的大小加上插入字符串的大小是否大于容量_capacity,如果大于需要先進行擴容,擴容大小為原字符串的大小加上插入字符串的大小。
    • 將插入的字符串拷貝到原字符串后面,拷貝大小為len+1,然后修改_size值。
  • 1.operator+=函數(shù)實現(xiàn):

    operator+=函數(shù)和append()函數(shù)一樣有兩種不同的實現(xiàn),在原string對象后增加單個字符和字符串。

    //string.h文件中聲明
    string& operator+=(char ch);         
    string& operator+=(const char* str); 
    //string.cpp文件中定義
    //增加單個字符
    Mystring::string& Mystring::string::operator+=(char ch)
    {push_back(ch);return *this;
    }
    //增加字符串
    Mystring::string& Mystring::string::operator+=(const char* str)
    {append(str);return *this;
    }
    

    2.實現(xiàn)原理:

    • 增加單個字符直接調用push_back()函數(shù),最后要返回this指針。
    • 增加字符串直接調用append(const char* str)函數(shù),最后返回this指針。

2.插入操作相關函數(shù)

  • insert()函數(shù)實現(xiàn):

    1.插入n個字符:

    //string.h文件中聲明
    void insert(size_t pos,size_t n,char ch);
    //string.cpp文件中定義
    void Mystring::string::insert(size_t pos,size_t n,char ch)
    {assert(pos<_size);if((_size+n)>_capacity){reserve(_size+n);}size_t end=_size;while(end>=pos&&end!=npos){_str[end+n]=_str[end];end--;}for(size_t i=0;i<n;i++){_str[pos+i]=ch;}_size+=n;}
    

    實現(xiàn)原理:

    • 如果原字符串大小加上插入的個數(shù)大于容量大小時,需要先進行擴容,擴容大小為原字符串大小加上插入的個數(shù)。
    • 將插入位置后面的數(shù)據(jù)依次往后移動n個位置。
    • 再將移動后空出來的位置插入n個字符ch。最后修改_size大小。

    2.插入字符串:

    //string.h文件中聲明
    void insert(size_t pos,const char*str);
    //string.cpp文件中定義
    void Mystring::string::insert(size_t pos,const char*str)
    {assert(pos<_size);size_t len=strlen(str);if(_size+len>_capacity){reserve(_size+len);}size_t end=_size;while(end>=pos&&end!=npos){_str[end+len]=_str[end];end--;}for(size_t i=0;i<len;i++){_str[pos+i]=str[i];}_size+=len;
    }
    

    實現(xiàn)原理:

    • 插入字符串和插入n個字符原理相同,不同點是,最后插入時,需要依次插入字符串的字符。

3.刪除操作相關函數(shù)

  • erase()函數(shù)實現(xiàn):

    //string.h中聲明
    void erase(size_t pos,size_t len=npos);
    //string.cpp文件中定義
    void Mystring::string::erase(size_t pos,size_t len)
    {assert(pos<_size);if(len==npos||pos+len>=_size){_size=pos;_str[_size]='\0';}else{size_t end=len+pos;while(end<=_size){_str[pos++]=_str[end++];}_size-=len;}
    }
    
  • 實現(xiàn)原理:

    • 刪除要分為兩種情況,第一種,如果刪除的個數(shù)大于_size或者len等于npos值,直接從pos位置將后面全部刪除。
    • 第二種,依次將后面的字符往前移動,從而達到刪除的目的。

4.測試

測試代碼如下:

void test4(){//創(chuàng)建一個空對象s1Mystring::string s1;//s1追加字符串hellos1.append("hello");cout<<s1<<endl;//s1追加字符串worlds1+="world";cout<<s1<<endl;//s1尾插字符!s1.push_back('!');cout<<s1<<endl;//在s1下標為6的位置插入***s1.insert(6,"***");cout<<s1<<endl;//刪除s1下標為10后面的所有字符s1.erase(10);cout<<s1<<endl;//刪除s1下標為5后面的三個字符s1.erase(5,3);cout<<s1<<endl;
}

測試結果如下:

在這里插入圖片描述

五.string類的流插入和流提取函數(shù)

  • 1.operator<<流插入函數(shù)實現(xiàn):

    //string.h文件中聲明
    ostream& operator<<(ostream& out,const string&s);
    //string.cpp文件中定義
    ostream& Mystring::operator<<(ostream& out,const string&s)
    {cout<<"operator<<"<<endl;for(auto e:s){out<<e;}return out;
    }
    
  • 1.operator>>流提取函數(shù)實現(xiàn):

    //string.h文件中聲明
    istream& operator>>(istream &in,string &s);
    //string.cpp文件中定義
    istream& Mystring::operator>>(istream &in, string &s)
    {cout<<"operator>>"<<endl;s.clear();char ch = in.get();// 處理前緩沖區(qū)前面的空格或者換行while (ch == ' ' || ch == '\n'){ch = in.get();}char buff[128];int i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 127){buff[i] = '\0';s += buff;i = 0;}ch = in.get();}if (i != 0){buff[i] = '\0';s += buff;}return in;
    }
    

測試代碼如下:

void test5(){Mystring::string s1;//輸入cin>>s1;//輸出cout<<s1<<endl;
}

在這里插入圖片描述

六.string類完整代碼

1.string.h頭文件代碼

#include<iostream>
#include<string>
#include<string.h>
#include<assert.h>
using namespace std;namespace Mystring{class string{public:static const size_t npos=-1;//構造函數(shù)string(const char* str = "");//析構函數(shù)~string();//拷貝構造函數(shù)string(const string&s);//賦值運算符重載string& operator=(const string&s);//c格式打印const char* c_str(){return _str;}//容量大小size_t size(){return _size;}size_t capacity(){return _capacity;}//擴容void reserve(size_t n);void resize(size_t n,char ch='\0');void clear(){_size=0;_str[_size]='\0';}//訪問方式char& operator[](size_t pos){assert(pos<_size);return _str[pos];}char& at(size_t pos){assert(pos<_size);return _str[pos];}//迭代器typedef char* iterator;iterator begin() {return _str;}iterator end() {return _str+_size;}typedef const char* const_iterator;const_iterator begin()const {return _str;}const_iterator end()const {return _str+_size;}//修改void push_back(char ch);            void append(char ch);                void append(const char* str);        string& operator+=(char ch);         string& operator+=(const char* str); void insert(size_t pos,size_t n,char ch);void insert(size_t pos,const char*str);void erase(size_t pos,size_t len=npos);//查找size_t find(char ch,size_t pos=0);size_t find(const char*str,size_t pos=0);//友元函數(shù)friend ostream& operator<<(ostream& out,const string&s);friend istream& operator>>(istream& in,string&s);private:int _size;int _capacity;char* _str;};//非string成員函數(shù)ostream& operator<<(ostream& out,const string&s);istream& operator>>(istream& in,string&s);
}

2.string.cpp函數(shù)定義文件代碼

#include"string.h"Mystring::string::string(const char* str)
:_size(strlen(str))
,_capacity(_size)
,_str(new char[_size+1])
{cout<<"string()"<<endl;memcpy(_str,str,_size+1);
}Mystring::string& Mystring::string::operator=(const string&s)
{cout<<"operator="<<endl;char* tmp=new char[s._capacity+1];memcpy(tmp,s._str,s._size+1);delete[] _str;_str=tmp;_capacity=s._capacity;_size=s._size;return *this;
}Mystring::string::~string(){cout<<"~string()"<<endl;delete[] _str;_str=nullptr;_size=0;_capacity=0;
}Mystring::string::string(const string&s)
{cout<<"string()"<<endl;_str=new char[s._capacity+1];strcpy(_str,s._str);_size=s._size;_capacity=s._capacity;
}void Mystring::string::reserve(size_t n)
{if(n>_capacity){char*tmp=new char[n+1];memcpy(tmp,_str,_size+1);delete[] _str;_str=tmp;_capacity=n;}
}void Mystring::string::resize(size_t n,char ch)
{if(n>_capacity){reserve(n);}if(n>_size){for(size_t i=_size;i<n;i++){_str[i]=ch;}}_size=n;_str[_size]='\0';}void Mystring::string::push_back(char ch)
{if(_size==_capacity){reserve(_capacity==0?4:2*_capacity);}_str[_size]=ch;_size++;_str[_size]='\0';
}void Mystring::string::append(char ch)
{push_back(ch);
}void Mystring::string::append(const char* str)
{size_t len=strlen(str);if(_size+len>_capacity){reserve(_size+len);}memcpy(_str+_size,str,len+1);_size+=len;
}Mystring::string& Mystring::string::operator+=(char ch)
{push_back(ch);return *this;
}Mystring::string& Mystring::string::operator+=(const char* str)
{append(str);return *this;
}size_t Mystring::string::find(char ch,size_t pos)
{assert(pos<_size);for(size_t i=pos;i<_size;i++){if(_str[i]==ch){return i;}}return npos;
}size_t Mystring::string::find(const char*str,size_t pos)
{assert(pos<_size);const char* ptr=strstr(_str+pos,str);if(ptr){return ptr-_str;}else{return npos;}
}void Mystring::string::insert(size_t pos,size_t n,char ch)
{assert(pos<_size);if((_size+n)>_capacity){reserve(_size+n);}size_t end=_size;while(end>=pos&&end!=npos){_str[end+n]=_str[end];end--;}for(size_t i=0;i<n;i++){_str[pos+i]=ch;}_size+=n;}void Mystring::string::insert(size_t pos,const char*str)
{assert(pos<_size);size_t len=strlen(str);if(_size+len>_capacity){reserve(_size+len);}size_t end=_size;while(end>=pos&&end!=npos){_str[end+len]=_str[end];end--;}for(size_t i=0;i<len;i++){_str[pos+i]=str[i];}_size+=len;
}void Mystring::string::erase(size_t pos,size_t len)
{assert(pos<_size);if(len==npos||pos+len>=_size){_size=pos;_str[_size]='\0';}else{size_t end=len+pos;while(end<=_size){_str[pos++]=_str[end++];}_size-=len;}
}ostream& Mystring::operator<<(ostream& out,const string&s)
{//cout<<"operator<<"<<endl;for(auto e:s){out<<e;}return out;
}istream& Mystring::operator>>(istream &in, string &s)
{cout<<"operator>>"<<endl;s.clear();char ch = in.get();// 處理前緩沖區(qū)前面的空格或者換行while (ch == ' ' || ch == '\n'){ch = in.get();}char buff[128];int i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 127){buff[i] = '\0';s += buff;i = 0;}ch = in.get();}if (i != 0){buff[i] = '\0';s += buff;}return in;
}

3.test.cpp測試文件代碼

#include"string.h"void test1(){//創(chuàng)建s1對象Mystring::string s1("hello world");//用s1對象拷貝構造s2對象Mystring::string s2(s1);//將s1對象賦值給s3對象Mystring::string s3("hello");s3=s1;
}void test2(){Mystring::string s1("hello world");//使用opreator[]打印s1for(size_t i=0;i<s1.size();i++){cout<<s1[i]<<" ";}cout<<endl;//使用普通對象的迭代器打印s1Mystring::string::iterator it=s1.begin();while(it!=s1.end()){cout<<*it<<" ";it++;}cout<<endl;//使用const對象的迭代器打印s2const Mystring::string s2("hello");Mystring::string::const_iterator rit=s2.begin();while(rit!=s2.end()){cout<<*rit<<" ";rit++;}cout<<endl;
}void test3(){Mystring::string s1("hello world");cout<<s1.size()<<" "<<s1.capacity()<<endl;//s1容量擴為15s1.reserve(15);cout<<s1.size()<<" "<<s1.capacity()<<endl;//s1容量擴為20,多余空間用字符a填充s1.resize(20,'a');cout<<s1.size()<<" "<<s1.capacity()<<endl;cout<<s1<<endl;//s1縮容為8,發(fā)生截斷s1.resize(8);cout<<s1.size()<<" "<<s1.capacity()<<endl;cout<<s1<<endl;
}void test4(){//創(chuàng)建一個空對象s1Mystring::string s1;//s1追加字符串hellos1.append("hello");cout<<s1<<endl;//s1追加字符串worlds1+="world";cout<<s1<<endl;//s1尾插字符!s1.push_back('!');cout<<s1<<endl;//在s1下標為6的位置插入***s1.insert(6,"***");cout<<s1<<endl;//刪除s1下標為10后面的所有字符s1.erase(10);cout<<s1<<endl;//刪除s1下標為5后面的三個字符s1.erase(5,3);cout<<s1<<endl;
}void test5(){Mystring::string s1;//輸入cin>>s1;//輸出cout<<s1<<endl;}int main()
{//test1();//test2();//test3();//test4();test5();return 0;
}

以上就是關于如何模擬實現(xiàn)string類的講解,如果哪里有錯的話,可以在評論區(qū)指正,也歡迎大家一起討論學習,如果對你的學習有幫助的話,點點贊關注支持一下吧!!!
在這里插入圖片描述

http://m.aloenet.com.cn/news/1291.html

相關文章:

  • 教育網站建設解決方案公司網站建設服務機構
  • 安陽網站制作如何增加網站權重
  • 在線教育網站模板網絡公司網絡營銷推廣方案
  • 網站版權 備案icp網絡公司名字大全
  • 填空秒懂網站女生seo專員很難嗎為什么
  • 長沙3合1網站建設寧波seo關鍵詞排名優(yōu)化
  • 做哪個網站的推廣最好網絡營銷電子版教材
  • b2b商貿網站系統(tǒng)域名反查
  • 新媒體運營師商丘seo
  • 汕頭網址模板建站培訓學校機構有哪些
  • 兼職建設網站西安自動seo
  • 快捷的網站建設排行榜百度seo關鍵詞排名查詢
  • 做爰全過程免費狐貍網站seo網站優(yōu)化流程
  • ppt做視頻模板下載網站有哪些100個關鍵詞
  • 自己做網站嗎百度店鋪怎么入駐
  • 重慶網站制seo關鍵詞怎么選
  • 網頁制作教程百度云網頁seo優(yōu)化
  • 九江網站建設優(yōu)化公司營銷的方法手段有哪些
  • 亞馬遜網網站建設規(guī)劃報告微信客戶管理
  • 福田做網站報價網站優(yōu)化推廣方法
  • 河南便宜網站建設搜索引擎營銷的簡稱是
  • 橋梁建設雜志網站運營培訓班學費大概多少
  • wordpress網站導航模板網絡營銷師證書有用嗎
  • 互聯(lián)網 網站建設搜狗收錄提交入口
  • 營銷型外貿網站制作鄭州網絡推廣平臺有哪些
  • 網站pv統(tǒng)計方法電商seo與sem是什么
  • 怎做連接網站百度手機關鍵詞排名工具
  • 日本做暖網站泰安百度推廣公司
  • h5網站網站建設今天發(fā)生的重大新聞
  • 新華區(qū)設計網站公司短視頻培訓要多少學費