国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

C++入門(mén)string類常用接口函數(shù)介紹 + 進(jìn)階【模擬實(shí)現(xiàn)string接口函數(shù)】

legendaryedu / 2689人閱讀

摘要:目錄類對(duì)象的常見(jiàn)構(gòu)造類對(duì)象的訪問(wèn)及遍歷操作迭代器介紹類對(duì)象的修改操作深淺拷貝問(wèn)題深拷貝傳統(tǒng)寫(xiě)法深拷貝的現(xiàn)代寫(xiě)法模擬實(shí)現(xiàn)構(gòu)造函數(shù)拷貝構(gòu)造函數(shù)交換函數(shù)拷貝賦值運(yùn)算符獲取對(duì)象的成員屬性重載可讀可寫(xiě)和可讀定義迭代器增容處理和函

string類對(duì)象的常見(jiàn)構(gòu)造

介紹常用的幾個(gè)string接口函數(shù),如果需要學(xué)習(xí)更多的請(qǐng)參考官方文檔: string構(gòu)造函數(shù).

函數(shù)名稱功能說(shuō)明
string() (重點(diǎn))構(gòu)造空的string類對(duì)象,即空字符串
string(const char* s) (重點(diǎn))用C-string來(lái)構(gòu)造string類對(duì)象
string(size_t n, char c)string類對(duì)象中包含n個(gè)字符c
string(const string&s) (重點(diǎn))拷貝構(gòu)造函數(shù)
string (const string& str, size_t pos, size_t len = npos)從str對(duì)象中由pos位置開(kāi)始截取len個(gè)長(zhǎng)度的字符,len > str長(zhǎng)度就結(jié)束
string (const char* s, size_t n)從s指向的字符數(shù)組中復(fù)制前n個(gè)字符。
void functest() {	//函數(shù)原型:string()     string s1;      //調(diào)用默認(rèn)構(gòu)造函數(shù)創(chuàng)建一個(gè)string對(duì)象,對(duì)象的內(nèi)容是空字符串    //類似于這種初始化方式:string s1("")		//函數(shù)原型:string(const char* s)     string s2("hello cpp");     //調(diào)用string的構(gòu)造函數(shù)用字符串去初始化一個(gè)string對(duì)象		//函數(shù)原型:string(const string&s)     string s3(s2);     //調(diào)用string類的拷貝構(gòu)造函數(shù)創(chuàng)建s3對(duì)象         //函數(shù)原型:string (const string& str, size_t pos, size_t len = npos)	string s4(s3, 0, 5);  	//從s3對(duì)象中由0位置開(kāi)始截取5個(gè)長(zhǎng)度的字符		char arr[] = "https://blog.csdn.net/m0_53421868?spm=1000.2115.3001.5343";	//函數(shù)原型:string (const char* s, size_t n)    string s5(arr, 5);    //截取字符數(shù)組的n個(gè)長(zhǎng)度字符	cout << s1 << endl;    cout << s2 << endl;    cout << s3 << endl;    cout << s4 << endl;    cout << s5 << endl;}

打印結(jié)果:

string類對(duì)象的訪問(wèn)及遍歷操作迭代器介紹

函數(shù)名稱功能說(shuō)明
operator[] (重點(diǎn))返回pos位置的字符,const string類對(duì)象調(diào)用
begin+ endbegin獲取第一個(gè)字符的迭代器 + end獲取最后一個(gè)字符下一個(gè)位置的迭代器
rbegin + rendbegin獲取第一個(gè)字符的迭代器 + end獲取最后一個(gè)字符下一個(gè)位置的迭代器
范圍forC++11支持

使用正向迭代器遍歷string對(duì)象

void functest() {    string s1;    string s2("hello cpp");        //返回字符串首字符的迭代器給sc,讓sc指向這個(gè)字符    string::iterator sc = s2.begin();    while (sc != s2.end())     {        cout << *sc << " ";        sc++;    }}

使用反向迭代器遍歷string對(duì)象

void functest() {    string s1;    string s2("abcdefg");	//返回最后一個(gè)字符的迭代器讓sc指向    string::reverse_iterator sc = s2.rbegin();    while (sc != s2.rend())     {        cout << *sc << " ";      	++sc;    }}

而以上兩種迭代器都是可以去修改對(duì)象的值的,還有一種只讀的迭代器不允許修改對(duì)象的值

void functest() {    string s1;    string s2("abcdefg");	    string::const_iterator sc = s2.begin();    while (sc != s2.end())     {    	//可讀但不能修改        cout << *sc++ ;     }}

反向只讀迭代器遍歷string對(duì)象

void functest() {    string s1;    string s2("abcdefg");    //返回const_reverse_iterator 的迭代器支持反向遍歷操作,    //但不支持修改    string::const_reverse_iterator sc = s2.rbegin();    while (sc != s2.rend())     {        cout << *sc++;          }}

總結(jié):以上幾種迭代器的操作比較簡(jiǎn)單,讀者可以結(jié)合文檔自己去使用

鏈接: 做題.
題目描述:
給定一個(gè)字符串,找到它的第一個(gè)不重復(fù)的字符,并返回它的索引。如果不存在,則返回 -1。

測(cè)試用例:

實(shí)現(xiàn)思路:

找出字符串中只出現(xiàn)一次的字符可以采用計(jì)數(shù)的方法,記錄每個(gè)字符在數(shù)組中出現(xiàn)的位置統(tǒng)計(jì)他出現(xiàn)的次數(shù),最后只出現(xiàn)一次的字符就是我們要找的字符

范圍for + operator[]

class Solution {public:    int firstUniqChar(string s) {        int count[26] = {0};        for(auto e : s)        {        	//記錄每個(gè)字符在count數(shù)組中出現(xiàn)的次數(shù)(相對(duì)映射)            count[e - "a"]++;        }        for(size_t i = 0; i < s.size(); i++)        {        	//檢查某個(gè)字符映射在數(shù)組中出現(xiàn)的次數(shù),        	//如果等于1就表示只出現(xiàn)一次            if(count[s[i] - "a"] == 1)            {                return i;            }        }        return -1;    }};

使用迭代器遍歷對(duì)象的源字符串中的字符再通過(guò)count數(shù)組計(jì)數(shù)

class Solution {public:    int firstUniqChar(string s) {        int count[26] = { 0 };        string::iterator sc = s.begin();        //sc接受s.begin返回的迭代器        while (sc != s.end())         {            count[*sc - "a"]++;            sc++;        }        for (size_t i = 0; i < s.size(); i++)         {            if (count[s[i] - "a"] == 1)            {                return i;            }        }        return -1;    }};

string類對(duì)象的修改操作

函數(shù)名稱功能說(shuō)明
push_back在字符串后尾插字符c
append在字符串后追加一個(gè)字符串
operator+= (重點(diǎn))在字符串后追加字符串str
c_str(重點(diǎn))返回C格式字符串
find + npos(重點(diǎn))從字符串pos位置開(kāi)始往后找字符c,返回該字符在字符串中的位置
rfind在字符串中搜索由參數(shù)指定的序列的最后一次出現(xiàn)時(shí)的下標(biāo)位置。
substr在str中從pos位置開(kāi)始,截取n個(gè)字符,然后將其返回
insert指定位置pos處插入一個(gè)字符串
erase從指定pos位置開(kāi)始刪除len個(gè)長(zhǎng)度的字符

插入操作:

void functest2() {    string s;    s.push_back("h");    s.push_back("e");    s.push_back("l");    s.push_back("l");    s.push_back("o");    cout << s << endl;//	hello    s.append("word");//	    helloword    cout << s << endl;    //append還可以指定一個(gè)迭代器區(qū)間,    //將這段區(qū)間的字符串追加到s對(duì)象// 函數(shù)原型:string& append (const string& str, size_t subpos, size_t sublen);    string s3("defgh");    s.append(s3, 2,3);	    //從字符串中下標(biāo)位置為2的字符起開(kāi)始截取3個(gè)字符追加到s對(duì)象    cout << s << endl;//hellowordfgh	//string成員函數(shù)operator+=同樣也支持追加字符串的操作	s += "abc";    cout << s << endl; //hellowordfghabc		//指定位置插入	//函數(shù)原型:string& insert (size_t pos, const char* s);	string s("abcdefg");    s.insert(0,"c");//err,參數(shù)是字符串,這樣使用不對(duì)    s.insert(0, "x");    //0位置處插入一個(gè)x,整體字符串往后挪動(dòng),不推薦使用,挪動(dòng)數(shù)據(jù)的效率太低}

需要注意的一些string成員函數(shù)c_str

string s("hello word");    cout << s << endl;	    //自定義類型的s在輸出的時(shí)候會(huì)    //調(diào)用重載的 operator<< (ostream& os, const string& str);    cout << s.c_str() << endl;    //s.c_str()函數(shù)返回的是一個(gè)c風(fēng)格的字符串他是內(nèi)置類型,    //使用的是全局的operator<<(cout, const char *)         cout << "------------------" << endl;    //所以會(huì)在輸出的時(shí)候各不相同    s.resize(20);    s += "!!!";    cout << s << endl;    cout << s.c_str() << endl;

效果:
1、調(diào)用內(nèi)置類型的operator<<(cout, const char *) 輸出字符串的時(shí)候遇到‘/0’就會(huì)停止
2、調(diào)用自定義類型的operator<< (ostream& os, const string& str)即使遇到‘/0’也不會(huì)停止,只有把字符串給完全遍歷完了才會(huì)停止遍歷

刪除操作:

void functest3() {    string s("abcdefg");    //函數(shù)原型:string& erase (size_t pos = 0, size_t len = npos);    //函數(shù)功能:指定pos位置處開(kāi)始,刪除len個(gè)長(zhǎng)度的字符    s.erase(1,2);    cout << s << endl;//adefg}

查找操作:
從前往后

//string拷貝構(gòu)造函數(shù)原型:				這里會(huì)給缺省值//string (const string& str, size_t pos, size_t len = npos);string buff1("test.cpp");int pos = buff1.find(".");if (pos != string::npos) //npos值是-1,類型是無(wú)符號(hào)整形,所以是整形的最大值,字符串并不會(huì)存儲(chǔ)這么長(zhǎng){    string buff2(buff1,pos, buff1.size() - pos);    //調(diào)用拷貝構(gòu)造函數(shù)創(chuàng)建buff2對(duì)象,    //從pos位置開(kāi)始截取len個(gè)長(zhǎng)度的字符串創(chuàng)建一個(gè)string對(duì)象        //也可以使用這種寫(xiě)法去截取后綴:    //即使使用了函數(shù)提供的缺省值也并不用過(guò)于擔(dān)心,npos是最大值也好   	//只會(huì)截取有效內(nèi)容,超過(guò)不管    string buff3(buff1,pos);	//不調(diào)用拷貝構(gòu)造函數(shù)同樣也能做到, substr截取	//函數(shù)原型:string substr (size_t pos = 0, size_t len = npos) const;	string buff4 = buff1.substr(pos);    cout << buff2 << endl;//.cpp}

從后往前

//函數(shù)原型://size_t rfind (const string& str, size_t pos = npos) const;//函數(shù)功能是返回指定參數(shù)在字符串中最后一次出現(xiàn)的位置string buff1("test.cpp.zip");int pos = buff1.rfind(".");if (pos != string::npos) {    string buff2(buff1, pos);    cout << buff2 << endl;}

使用string成員函數(shù)查找網(wǎng)絡(luò)域名跟協(xié)議使用舉例,詳細(xì)解釋請(qǐng)看注釋

//返回協(xié)議名string GetAgreeMent(const string& s){    //查找"://",找到返回該字符串的起始下標(biāo)位置    size_t pos = s.find("://");    if (pos != string::npos)    {        //由于是左閉右開(kāi)區(qū)間【0,5),所以只需要pos - 0就能計(jì)算出協(xié)議名的長(zhǎng)度        return s.substr(0, pos - 0);    }    else    {        //找不到返回空串        return string();    }}//返回域名string GetDomain(const string& s) {    //查找"://",找到返回該字符串的起始下標(biāo)位置    size_t pos = s.find("://");    if (pos != string::npos)     {        //計(jì)算出域名的起始下標(biāo)位置,從這個(gè)位置開(kāi)始查找"/"        size_t start = pos + 3;        size_t end = s.find("/", start);        if (end != string::npos)         {            //同樣的左閉右開(kāi)區(qū)間,開(kāi)區(qū)間的位置減去閉區(qū)間的位置就是字符串的長(zhǎng)度            return s.substr(start, end - start);        }        else        {            //找不到返回空串            return string();        }    }    else    {        //找不到返回空串        return string();    }    }void functest4() {    string url1 = "https://blog.csdn.net/m0_53421868?spm=1000.2115.3001.5343";    string url2 = "https://bbs.csdn.net/forums/mzt";    cout << GetDomain(url1) << endl;    cout << GetAgreeMent(url1) << endl;    cout << GetDomain(url2) << endl;    cout << GetAgreeMent(url2) << endl;}

string類對(duì)象的容量操作

函數(shù)名稱功能說(shuō)明
size(重點(diǎn))統(tǒng)計(jì)字符個(gè)數(shù)
length返回字符串有效字符長(zhǎng)度
capacity返回空間總大小
empty (重點(diǎn))檢測(cè)字符串釋放為空串,是返回true,否則返回false
clear (重點(diǎn))清空有效字符,將size置零
reserve (重點(diǎn))為字符串預(yù)留空間
resize (重點(diǎn))將有效字符的個(gè)數(shù)該成n個(gè),多出的空間用字符c填充

測(cè)試:

string s;s.resize(10);//插入10個(gè)"/0",默認(rèn)以"/0"填充cout << s << endl;string s1;s1.resize(10,"x");//指定插入10個(gè)字符,以"x"填充cout << s1 << endl;string s3("hello word");s3.resize(20,"x"); //將空間擴(kuò)容到20,多出來(lái)的空間用"x"填充,并且是尾插的方式cout << s3 << endl;

需要注意的一些增容函數(shù)

與resize函數(shù)相似的有reserve 他并不會(huì)改變空間的內(nèi)容,只做增容

深淺拷貝問(wèn)題

淺拷貝一般都是在拷貝構(gòu)造一個(gè)對(duì)象的時(shí)候完成值拷貝的一個(gè)過(guò)程,因?yàn)槲覀儾粚?xiě)編譯器默認(rèn)的生成的拷貝構(gòu)造函數(shù)完成的是淺拷貝,這樣對(duì)象出了作用域開(kāi)始調(diào)用析構(gòu)函數(shù)的時(shí)候會(huì)導(dǎo)致同一塊空間被釋放兩次,就會(huì)引發(fā)程序崩潰

namespace mzt {    class string     {    public:   		 //重載operator<<        friend  ostream &operator<< (ostream &out, string &str)        {            out << str._str << endl;            return out;        }                string(const char* str = "")            : _str(new char[strlen(str) + 1])            , _size(0)            ,_capacity(0)        {            strcpy(_str, str);        }        //我們不寫(xiě)編譯器會(huì)默認(rèn)生成一個(gè)拷貝構(gòu)造函數(shù)完成淺拷貝       /* string(const string & str)             : _str(new char[strlen(str._str) + 1])        {           strcpy(_str, str._str);        }*/                ~string()        {            delete[] _str;            _str = nullptr;        }    private:        char* _str;        size_t _capacity;        size_t _size;    };    void stringtest()    {        mzt::string s("hello world");        mzt::string s1(s);        cout << s;        cout << s1;    }}

即使打印出了hello world,但是這個(gè)程序還是存在問(wèn)題,因?yàn)閮蓚€(gè)對(duì)象的_str指針指向的是同一塊空間所以當(dāng)被delete的時(shí)候就會(huì)被析構(gòu)兩次,這是不被允許的,解決辦法深拷貝,重新創(chuàng)建一個(gè)空間,并把值存過(guò)去,讓兩個(gè)對(duì)象之間的內(nèi)容互不影響

深拷貝傳統(tǒng)寫(xiě)法

namespace mzt {    class string     {    public:        friend  ostream &operator<< (ostream &out, string &str)        {            out << str._str << endl;            return out;        }        string(const char* str = "")            : _str(new char[strlen(str) + 1])            , _size(0)            ,_capacity(0)        {            strcpy(_str, str);        }        //我們不寫(xiě)編譯器會(huì)默認(rèn)生成一個(gè)拷貝構(gòu)造函數(shù)完成淺拷貝        //解決辦法深拷貝,開(kāi)辟一塊新的空間,把值拷貝過(guò)去        string(const string & str)             : _str(new char[strlen(str._str) + 1])        {           strcpy(_str, str._str);        }        //重載operator=也是一樣的做法,        //開(kāi)空間拷貝值避免出現(xiàn)淺拷貝的問(wèn)題        string& operator=(const string& s)         {            if (this != &s)             {                delete[] _str;                _str = new char[strlen(s._str) + 1];                strcpy(_str, s._str);            }            return *this;        }                ~string()        {            delete[] _str;            _str = nullptr;        }            private:        char* _str;        size_t _capacity;        size_t _size;    };        void stringtest()    {        mzt::string s("hello world");        mzt::string s1(s);        cout << s;        cout << s1;    }}

深拷貝的現(xiàn)代寫(xiě)法

推薦使用現(xiàn)代深拷貝的方法:
原因1: 代碼簡(jiǎn)潔
原因2:可讀性強(qiáng)

//我們不寫(xiě)編譯器會(huì)默認(rèn)生成一個(gè)拷貝構(gòu)造函數(shù)完成淺拷貝//解決辦法做深拷貝string(const string &s)	: _str(nullptr)	//_str必須初始化為nullptr,才去交換tmp指針,	//否則_str就是野指針了,當(dāng)tmp出了作用域析構(gòu)野指針會(huì)有非法內(nèi)存訪問(wèn){    //調(diào)用構(gòu)造函數(shù)利用s._str做參數(shù)構(gòu)造臨時(shí)對(duì)象    string tmp(s._str);    //將臨時(shí)對(duì)象的指針_str和this._str一交換    swap(tmp._str, _str);    //臨時(shí)對(duì)象出了作用域就銷毀了,會(huì)自動(dòng)調(diào)用它的析構(gòu)函數(shù)}//拷貝賦值運(yùn)算符現(xiàn)代寫(xiě)法string& operator=(string s)//s通過(guò)調(diào)用拷貝構(gòu)造函數(shù)完成的深拷貝{    //還是一樣的思路,由于拷貝構(gòu)造函數(shù)已經(jīng)被我們實(shí)現(xiàn)了,    //所以就不會(huì)存在淺拷貝的問(wèn)題,所以通過(guò)值傳遞,即使    //棧幀被銷毀了,兩個(gè)對(duì)象也互不影響,這也是一種復(fù)用的方法    //直接上手交換指針this._str和s._str    swap(_str, s
                 
               
              

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/123192.html

相關(guān)文章

  • [C/C++]詳解STL容器1--string的功能和模擬實(shí)現(xiàn)(深淺拷貝問(wèn)題)

    摘要:本文介紹了類的常用接口的使用,并對(duì)其進(jìn)行了模擬實(shí)現(xiàn),對(duì)模擬實(shí)現(xiàn)中涉及到的深淺拷貝問(wèn)題進(jìn)行了解析。在此之前,必須提到一個(gè)經(jīng)典問(wèn)題。為了解決淺拷貝問(wèn)題,所以中引入了深拷貝。但是實(shí)際使用中需要是第一個(gè)形參對(duì)象,才能正常使用。 本文介紹了string類的常用接口的使用,并對(duì)其進(jìn)行了模擬實(shí)現(xiàn),對(duì)模擬實(shí)...

    tianren124 評(píng)論0 收藏0
  • Java進(jìn)階之路

    摘要:探索專為而設(shè)計(jì)的將探討進(jìn)行了何種改進(jìn),以及這些改進(jìn)背后的原因。關(guān)于最友好的文章進(jìn)階前言之前就寫(xiě)過(guò)一篇關(guān)于最友好的文章反響很不錯(cuò),由于那篇文章的定位就是簡(jiǎn)單友好,因此盡可能的摒棄復(fù)雜的概念,只抓住關(guān)鍵的東西來(lái)講,以保證大家都能看懂。 周月切換日歷 一個(gè)可以進(jìn)行周月切換的日歷,左右滑動(dòng)的切換月份,上下滑動(dòng)可以進(jìn)行周,月不同的視圖切換,可以進(jìn)行事件的標(biāo)記,以及節(jié)假日的顯示,功能豐富 Andr...

    sushi 評(píng)論0 收藏0
  • 【從零入門(mén)系列-3】Spring Boot 之 數(shù)據(jù)庫(kù)操作

    摘要:編寫(xiě)測(cè)試用例代碼打開(kāi)框架自動(dòng)生成的測(cè)試代碼文件編寫(xiě)測(cè)試用例,測(cè)試增刪改查效果,測(cè)試代碼如下注釋,它可以對(duì)類成員變量方法及構(gòu)造函數(shù)進(jìn)行標(biāo)注,完成自動(dòng)裝配的工作。 文章系列 【從零入門(mén)系列-0】Sprint Boot 之 Hello World 【從零入門(mén)系列-1】Sprint Boot 之 程序結(jié)構(gòu)設(shè)計(jì)說(shuō)明 【從零入門(mén)系列-2】Sprint Boot 之 數(shù)據(jù)庫(kù)實(shí)體類 前言 前一章...

    Leo_chen 評(píng)論0 收藏0
  • 熬夜爆肝!C++核心STL容器知識(shí)點(diǎn)匯總整理【3W字干貨預(yù)警 建議收藏】

    摘要:拷貝構(gòu)造函數(shù)示例構(gòu)造無(wú)參構(gòu)造函數(shù)總結(jié)容器和容器的構(gòu)造方式幾乎一致,靈活使用即可賦值操作功能描述給容器進(jìn)行賦值函數(shù)原型重載等號(hào)操作符將區(qū)間中的數(shù)據(jù)拷貝賦值給本身。清空容器的所有數(shù)據(jù)刪除區(qū)間的數(shù)據(jù),返回下一個(gè)數(shù)據(jù)的位置。 ...

    wayneli 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<