青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

huaxiazhihuo

 

基于堆棧上的字符串實(shí)現(xiàn)

           C++中,由于字符串一開始并非內(nèi)置的類型,于是,史前時(shí)代,江湖上出現(xiàn)了種種的字符串,各有各的優(yōu)點(diǎn),但自然,也各有各的缺陷,群雄割據(jù),天下大亂,民不聊生。大伙兒盼星星,盼月亮,盼著真正的字符串能出來(lái)一統(tǒng)江湖,好不容易,等到1998C++標(biāo)準(zhǔn)出來(lái)了,官方的字符串string終于露面了,自然,它并不是語(yǔ)言內(nèi)置支持的,而是在STL庫(kù)中。當(dāng)然,字符串這東西,就算要在C++編譯器的層面上給予支持,其實(shí)也很不容易。可是,這個(gè)官方的string,單純它復(fù)雜的模板定義和那一大陀函數(shù)成員,就足以嚇退眾多意志不堅(jiān)定之人。好了,好不容易,鼓起勇氣,再仔細(xì)瞅瞅string中的東西,發(fā)現(xiàn)它也不是很美妙,既不強(qiáng)大,部分函數(shù)的功能存在重復(fù)又或者STL的算法中已有提供,更要命的是,效率也不怎么高??傊荒苷f(shuō)string的設(shè)計(jì)不如史前的各種stringS,但也強(qiáng)不到那里去。當(dāng)然,官方的總比非官方的更具權(quán)威,但每次使用string時(shí),想到它背地里除了正常字符串操作之外,還可能做了各種的低效的內(nèi)存分配釋放的操作,又或者線程安全,又或者引用計(jì)數(shù),內(nèi)心就一直惴惴不安。于是,寧愿一再小心翼翼地用著字符數(shù)組。但是,用得多了,也很郁悶,字符數(shù)組自然高效、靈活,但總是要千編一律地一再寫著容易出錯(cuò)的代碼,我脆弱的心靈終于頭暈眼花了。于是,我決定按照自己的意愿寫一個(gè)字符串,不敢欲與群雄爭(zhēng)鋒,只是,為了能夠在自己的代碼中,替換字符數(shù)組。我對(duì)它的要求是,字符數(shù)組能做到的事情,它也要做到,并且,效率上,絕不妥協(xié)。

          俗話說(shuō),過(guò)早的優(yōu)化是萬(wàn)惡之源。但在此,在設(shè)計(jì)本家字符串時(shí),一開始,就要考慮到效率的細(xì)節(jié)上去了。首先,它要支持堆棧變量的形式,不要它進(jìn)行內(nèi)存的分配釋放操作,就好像堆棧上的字符數(shù)組那樣。咦,好像很神奇,其實(shí),只要想到TR1中那個(gè)經(jīng)典的array,通過(guò)使用神奇的模板技術(shù),就有辦法做到了。所以,此字符串的使用好比這樣子,CStackString <MAX_PATH> sFile,暫時(shí)假定這個(gè)字符串的名字叫CStackString

          但是,使用模板之后,字符串的字符數(shù)組的長(zhǎng)度只要不一樣,它們就都屬于不同類型變量,并且之間還都不兼容呢,雖然它們都是字符串。此外,還會(huì)編譯器還將生產(chǎn)出一堆重復(fù)的代碼。這無(wú)論如何,都不能忍受。于是,自然而然,就想到了繼承。CStackString模板類繼承于非模板的mybasestringmybasestring中實(shí)現(xiàn)了CStackString的各種各樣的操作,而CStackString只要仿照array那樣子,定義好自己的數(shù)據(jù)成員即可。嗯,還是看看代碼,馬上就明白到底是怎么一回事了。


class CMyBaseString
{
public:
    typedef size_t size_type;
    typedef 
char *pointer;
    typedef 
const char *const_pointer;
    typedef CMyBaseString _Myt;

public:
    
char operator[](size_type nPos)const
    
{
        assert(nPos 
< m_nLen);
        
return m_str[nPos];
    }


    const_pointer c_str()
const return m_str; }

    const_pointer right(size_type nLen)
const
    
{
        assert(nLen 
< m_nLen);
        
return m_str+m_nLen-nLen;
    }


    
int compare(const_pointer str)const
    
{
        
return strcmp(m_str, str);
    }


    _Myt
& assign(const char* str)
    
{
        m_nLen 
= strlen(str);
        assert(m_nLen 
< m_nBuffSize);
        strcpy(m_str, str);
        
return *this;
    }


    _Myt
& append(const_pointer str)
    
{
        size_type nLen 
= strlen(str);
        assert(m_nLen 
+ nLen < m_nBuffSize);
        strcpy(m_str
+m_nLen, str);
        m_nLen 
+= nLen;
        
return *this;
    }


    _Myt
& format(const_pointer sFormat,  )
    
{
        va_list argList;
        va_start( argList, sFormat );
        m_nLen 
= vsprintf(m_str, sFormat, argList);
        va_end( argList );
        assert(m_nLen 
< m_nBuffSize);
        
return *this;
    }


    
//.

protected:
    CMyBaseString(pointer sBuf, size_type nBuffSize)
    
{
        m_nBuffSize 
= nBuffSize;
        m_nLen 
= 0;
        m_str 
= sBuf;
        m_str[
0= 0;
    }


private:
    size_type m_nBuffSize;
    size_type m_nLen;
    pointer m_str;
}
;

template
<size_t _size>
class CStackString : public CMyBaseString
{
public:
    CStackString(
const char* str) : CMyBaseString(m_sMine, _size) { assign(str);}
    CStackString() : CMyBaseString(m_sMine, _size) 
{}

private:
    
char m_sMine[_size];
}
;
int main()
{
    CStackString
<20> sTest("hello");
    cout 
<< sTest.c_str() << endl;
    cout 
<< sTest.right(3<< endl;
    
return 0;
}

          于是通過(guò)基類mybasestring,各種不同類型的template CStackString就又聯(lián)系在一塊了。Mybasestring可看成定義了數(shù)據(jù)接口的基類,其子類的頭部數(shù)據(jù)必須與它保持一致,嗯,很好。然后,在mybasestring中實(shí)現(xiàn)的各種功能,都可以用在mystring身上了,而CStackString中無(wú)須實(shí)現(xiàn)任何功能,它只負(fù)責(zé)在堆棧上分配內(nèi)存。所以,mybasestring不僅可以用在堆棧上,還能用于堆上,只要再繼續(xù)定義一個(gè)能在堆上分配內(nèi)存的mybasestring的子類即可,然后都能相容于堆棧上的CStackString字符串。

          ……。 經(jīng)過(guò)一番努力,這個(gè)字符串類幾乎包含了字符數(shù)組的一切基本功能,基本上可代替字符數(shù)組了。為了能夠用到STL中的各種算法,再在其上增加一些返回迭代器的函數(shù),好比begin,end,rbegin,rend,它們都很容易實(shí)現(xiàn)。還有,為了使用起來(lái)更加友好方便更具效率,貌似應(yīng)該再實(shí)現(xiàn)一些全局操作符的重載運(yùn)算;……;好了,打住。如果打算將這個(gè)字符串很好地融入到STL中,需要做出更多的努力。原本只打算代替字符數(shù)組而已。代碼在VC2005以上版本編譯時(shí),會(huì)出現(xiàn)一些警告,可以用#pregma的指令將其disable掉,或者使用其中的所謂的安全字符串操作函數(shù)。

          好不容易,終于就實(shí)現(xiàn)了一個(gè)基于堆棧上的字符串,它是窄字符的。別忘了,還有寬字符的字符串呢。這也沒什么,只須將mybasestring重命名為CMyBaseStringACStackString改為CStackStringA。然后再分別實(shí)現(xiàn)與CMyBaseStringACStackStringA同樣接口的CMyBaseStringWCStackStringW。然后,再針對(duì)UNICODE,Typedefdefined一對(duì)CMyBaseStringTCStackStringT。在這里,并不想模仿STL中的stringMFC中的CString那樣子,template一個(gè)basic_stringsimple_string),然后分別進(jìn)行模板特化,近來(lái)越看越覺得這種模板特化的方式相當(dāng)惡心,只是將代碼搞得更加復(fù)雜,卻沒帶來(lái)多大的好處。

          相比于其他的字符串實(shí)現(xiàn),這個(gè)mybasestring不過(guò)是將內(nèi)存分配拱手讓人罷了。這樣一來(lái),就帶來(lái)一些新的問(wèn)題。首先,它要假設(shè)其子類給它分配了足夠的內(nèi)存,不過(guò),在C++傳統(tǒng),經(jīng)常假設(shè)用戶分配了足夠的內(nèi)存;然后,因?yàn)槊撾x了內(nèi)存管理,有一些功能自然也就無(wú)法實(shí)現(xiàn)出來(lái)了,C的字符串函數(shù)也還不是這樣,當(dāng)緩沖溢出時(shí),該崩潰就還得崩潰。

          再次向C++的無(wú)所不能頂禮膜拜。C++,你是電,你是光, 你是唯一的神話, 我只愛你,You are my Super Star

          再次聲明,本字符串只為取代字符數(shù)組,至于其它的種種無(wú)理要求,均不在本座的考慮范圍之內(nèi)。

posted on 2012-06-08 01:11 華夏之火 閱讀(2781) 評(píng)論(13)  編輯 收藏 引用 所屬分類: c++技術(shù)探討

評(píng)論

# re: 高效、實(shí)用、安全的字符串,語(yǔ)法糖?奇技淫巧? 2012-06-08 08:39 Richard Wei

依賴于編譯器的內(nèi)存布局, 不敢用。
C++11新增了array類來(lái)替代C型的原始數(shù)組。  回復(fù)  更多評(píng)論   

# re: 高效、實(shí)用、安全的字符串,語(yǔ)法糖?奇技淫巧? 2012-06-08 09:04 華夏之火

是的,這個(gè)設(shè)計(jì)很丑陋很限制。我已作了修改@Richard Wei
  回復(fù)  更多評(píng)論   

# re: 高效、實(shí)用、安全的字符串,語(yǔ)法糖?奇技淫巧?[未登錄] 2012-06-08 09:20 春秋十二月

內(nèi)存分配存儲(chǔ)方式可作為一種策略,作為字符串的模板參數(shù),形如std::allocator。不必弄子類定制。  回復(fù)  更多評(píng)論   

# re: 基于堆棧上的字符串實(shí)現(xiàn) 2012-06-08 09:52 華夏之火

代碼中,我又作了修改。至于形如std::allocator的那種定制,也有其不足,比如,vector,因?yàn)椴捎貌煌膕td::allocator的容器,都屬于不同的類型的vector,并且vector之間還不兼容呢@春秋十二月
  回復(fù)  更多評(píng)論   

# re: 基于堆棧上的字符串實(shí)現(xiàn) 2012-06-08 12:05 春秋十一月

用alloc來(lái)分配嘛,也是堆棧,一樣的效果,只要不是用malloc/HeapAlloc就行。這樣模板都不需要了。  回復(fù)  更多評(píng)論   

# re: 基于堆棧上的字符串實(shí)現(xiàn) 2012-06-08 13:19 zgpxgame

會(huì)導(dǎo)致代碼膨脹,如果只是內(nèi)存問(wèn)題可以考慮換一個(gè)基于棧的內(nèi)存分配器  回復(fù)  更多評(píng)論   

# re: 基于堆棧上的字符串實(shí)現(xiàn) 2012-06-08 13:46 華夏之火

基于棧的內(nèi)存分配器?在下也想看到,能否推薦一下。至于代碼膨脹,在這里的實(shí)現(xiàn)中,自然不會(huì)存在,你應(yīng)該知道WHY的@zgpxgame
  回復(fù)  更多評(píng)論   

# re: 基于堆棧上的字符串實(shí)現(xiàn) 2012-06-08 13:58 華夏之火

_alloca,在C++中,貌似并不是很推薦,據(jù)說(shuō)會(huì)帶來(lái)一些什么問(wèn)題@春秋十一月
  回復(fù)  更多評(píng)論   

# re: 基于堆棧上的字符串實(shí)現(xiàn) 2012-09-03 02:28 zgpxgame

我想說(shuō)的代碼膨脹是指如果代碼中使用了CStackString<1>......CStackString<N>會(huì)導(dǎo)致編譯器生成N個(gè)類,當(dāng)然如果只取一個(gè)最大N使用這個(gè)類也就不存在這個(gè)問(wèn)題了。 我個(gè)人不主張去重新實(shí)現(xiàn)一個(gè)棧string,而是去實(shí)現(xiàn)一個(gè)棧分配器,這里有現(xiàn)成的例子:http://src.chromium.org/viewvc/chrome/trunk/src/base/stack_container.h@華夏之火
  回復(fù)  更多評(píng)論   

# re: 基于堆棧上的字符串實(shí)現(xiàn) 2012-09-05 11:01 華夏之火

CStackString<1>......CStackString<N>會(huì)導(dǎo)致編譯器生成N個(gè)類,確實(shí)會(huì)生成這么多類,但是,這些類的函數(shù)都在基類中了,只有一分。C++中,最后的執(zhí)行文件中,不存在類這個(gè)概念,只有類的函數(shù),也即是函數(shù)。至于構(gòu)造函數(shù),則全部被內(nèi)聯(lián)@zgpxgame
  回復(fù)  更多評(píng)論   

# re: 基于堆棧上的字符串實(shí)現(xiàn) 2012-09-05 17:35 zgpxgame

恩,可以。 如果字符串類實(shí)現(xiàn)的再完善些也未嘗不可 @華夏之火
  回復(fù)  更多評(píng)論   

# re: 基于堆棧上的字符串實(shí)現(xiàn)[未登錄] 2012-10-20 11:32 無(wú)名

這也許會(huì)使每個(gè)字符串對(duì)象多用掉四字節(jié)內(nèi)存  回復(fù)  更多評(píng)論   

# re: 基于堆棧上的字符串實(shí)現(xiàn)[未登錄] 2012-10-20 11:35 無(wú)名

所以根據(jù)情況做不同取舍吧  回復(fù)  更多評(píng)論   

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

留言簿(6)

隨筆分類

隨筆檔案

搜索

積分與排名

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产日韩久久| 欧美高清视频www夜色资源网| 亚洲电影有码| 欧美伊人久久久久久久久影院| 亚洲高清色综合| 国产日韩在线看| 欧美亚州在线观看| 欧美精品一区二区三区在线看午夜| 久久国产精彩视频| 亚洲自拍偷拍网址| 一本久久综合| 日韩视频专区| 亚洲精品一区在线观看| 欧美成年人网| 另类av导航| 久久久久久久激情视频| 久久av一区二区三区漫画| 亚洲小说欧美另类社区| 亚洲美女视频在线观看| 亚洲国产精品va在看黑人| 伊人精品成人久久综合软件| 国产精品视频yy9099| 欧美午夜a级限制福利片| 欧美激情第8页| 欧美激情中文字幕一区二区| 免费一区视频| 免费一级欧美片在线播放| 美女诱惑黄网站一区| 久久免费视频网站| 美女999久久久精品视频| 免费av成人在线| 免费一区二区三区| 欧美fxxxxxx另类| 欧美国产视频在线观看| 欧美久久九九| 欧美日韩人人澡狠狠躁视频| 欧美日韩成人一区| 国产精品久久久久久久久久免费 | 午夜日韩av| 午夜精品久久久久久99热| 午夜精品久久久久久久久久久久| 亚洲永久免费av| 午夜视频久久久| 久久精品网址| 美女国内精品自产拍在线播放| 久久综合九色综合欧美狠狠| 欧美成人精品影院| 亚洲欧洲一级| 亚洲视频一区二区| 午夜欧美大片免费观看| 久久久www成人免费精品| 久久一二三区| 欧美伦理视频网站| 国产精品嫩草影院一区二区| 国产欧美日韩精品一区| 尤物精品国产第一福利三区 | 国产一区二区精品久久99| 黄网动漫久久久| 日韩手机在线导航| 欧美一级视频| 免费不卡视频| av不卡在线观看| 欧美在线观看一区二区三区| 欧美成人精品高清在线播放| 国产精品免费看片| 亚洲电影第三页| 一区二区高清视频在线观看| 香蕉尹人综合在线观看| 欧美成人69| 宅男精品导航| 麻豆av福利av久久av| 国产精品久久| 亚洲黄色免费网站| 欧美一区二区在线免费观看 | 在线视频亚洲| 久久久午夜视频| 欧美午夜理伦三级在线观看| 国内精品伊人久久久久av影院| 亚洲精品国产精品乱码不99| 西瓜成人精品人成网站| 亚洲福利视频网站| 亚洲欧美三级伦理| 欧美人与禽性xxxxx杂性| 国产一区二区主播在线| 一区二区三区毛片| 欧美成人a视频| 欧美亚洲一区三区| 欧美性大战久久久久久久| 伊人精品在线| 欧美专区日韩视频| 亚洲精品国久久99热| 久久狠狠亚洲综合| 国产精品一区二区久久国产| 亚洲精品一区在线观看| 久久精品一区二区三区四区| 一本色道综合亚洲| 欧美高清视频在线观看| 国内精品国语自产拍在线观看| 亚洲视频一区二区免费在线观看| 免费视频亚洲| 久久精品卡一| 国产欧美精品在线| 亚洲一区二区三区国产| 亚洲国产精品第一区二区| 欧美在线一二三| 国产精品乱码久久久久久| 99精品国产一区二区青青牛奶| 蜜桃av噜噜一区二区三区| 欧美一级大片在线免费观看| 国产精品第十页| 在线一区视频| 亚洲麻豆国产自偷在线| 欧美阿v一级看视频| 在线观看av不卡| 久久综合久色欧美综合狠狠| 午夜在线a亚洲v天堂网2018| 欧美午夜一区二区福利视频| 日韩一本二本av| 亚洲人成高清| 欧美高潮视频| 亚洲美女电影在线| 亚洲国产综合在线| 欧美破处大片在线视频| 亚洲精品久久| 亚洲欧洲另类国产综合| 欧美福利视频在线| 日韩一级成人av| 99精品久久久| 欧美视频中文在线看| 亚洲欧美日韩国产综合| 亚洲免费在线| 国产亚洲欧美另类中文| 久久久精彩视频| 久久精品视频在线看| 在线看国产日韩| 欧美国产日本韩| 欧美精品一区二区三| 在线视频一区二区| 亚洲视频播放| 国产日韩欧美成人| 久久亚洲国产精品一区二区 | 国产欧美高清| 久久亚洲午夜电影| 久久婷婷麻豆| 一区二区三区高清在线| 亚洲午夜在线观看视频在线| 国产女同一区二区| 久久久蜜臀国产一区二区| 久久伊人精品天天| 亚洲久久在线| 亚洲一区美女视频在线观看免费| 国产精品一区二区三区乱码| 久久久国产精品一区| 美国成人直播| 亚洲你懂的在线视频| 欧美一级专区免费大片| 亚洲日本激情| 一区二区三区你懂的| 国产一区亚洲一区| 亚洲人成啪啪网站| 国产欧美精品日韩| 欧美激情一区三区| 国产精品高潮久久| 美女主播视频一区| 欧美日韩三级电影在线| 久久久999| 欧美精品日韩综合在线| 欧美一区二区三区精品| 免费影视亚洲| 香蕉久久一区二区不卡无毒影院 | 一本色道88久久加勒比精品| 亚洲图片欧美日产| 亚洲国产天堂网精品网站| 一区二区精品国产| 亚洲大胆av| 亚洲一区在线观看免费观看电影高清| 韩国av一区二区三区| 亚洲美女黄网| 亚洲国产成人av在线| 亚洲少妇在线| 亚洲国产精品激情在线观看| 一区二区三区日韩欧美| 亚洲第一搞黄网站| 亚洲欧美韩国| 一二三四社区欧美黄| 久久久久国产一区二区三区| 亚洲一区二区三区中文字幕| 久久久久在线观看| 校园春色综合网| 欧美理论片在线观看| 久久深夜福利| 国产精品亚洲人在线观看| 亚洲经典视频在线观看| 黄色亚洲大片免费在线观看| 一区二区三区福利| 99精品欧美一区二区三区| 久久久久久一区| 久久国产高清| 国产精品人人做人人爽| 亚洲免费观看|