• <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>

            專(zhuān)職C++

            不能停止的腳步

              C++博客 :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
              163 Posts :: 7 Stories :: 135 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(28)

            我參與的團(tuán)隊(duì)

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            一個(gè)純C++簡(jiǎn)陋字符串實(shí)現(xiàn)說(shuō)明,之前是發(fā)的原代碼,結(jié)果太長(zhǎng)。無(wú)法讓大家看清。不好意思啊。
            其實(shí)中的設(shè)計(jì)很簡(jiǎn)單,首先是數(shù)據(jù)成員設(shè)計(jì),只有一個(gè)指針。也就是sizeof()它的時(shí)候,為4(32位系統(tǒng)下),而STL的string的sizeof()是32。默認(rèn)情況下,是不會(huì)配置內(nèi)存的,相當(dāng)于定義了一個(gè)空指針。這個(gè)指針類(lèi)型是T *。之所以使用T *,是因?yàn)檫@樣調(diào)試的時(shí)候,可以看到該字符串內(nèi)容是什么。如果你定義成void *,那就什么也看不到了。
            在XStringBase定義如下:
            * m_Data;            ///<數(shù)據(jù)指針

            一但它有數(shù)據(jù)后,它就指向字符串描述結(jié)構(gòu)的字符串內(nèi)容部分。在這個(gè)字符串前面,還有8?jìng)€(gè)字節(jié)的字符串頭。結(jié)構(gòu)體定義如下
                    ///字符串結(jié)構(gòu)結(jié)構(gòu)體
                    struct SStringStruct
                    {
                        XInt Length;        
            ///<尺寸
                        XInt Capacity;        ///<當(dāng)前字符串的容量
                        //Data                ///<當(dāng)前數(shù)據(jù)指針?biāo)诘奈恢?br>        };
            有兩個(gè)內(nèi)容,一個(gè)是當(dāng)前字符串的長(zhǎng)度。不含結(jié)尾0,一個(gè)是當(dāng)前申請(qǐng)內(nèi)存的內(nèi)存大小:容量。
            通過(guò)下面的函數(shù),取得字符定義的結(jié)構(gòu)體:
            SStringStruct * getOriData() 
            {    
                
            return ((SStringStruct *)m_Data) - 1;
            }
            這樣getOriData()->Length就是字符串的長(zhǎng)度了,getOriData()->Capacity就是它的容量了。
                    ///取當(dāng)前容量
                    XInt getCapacity() const
                    {
                        XInt iRet 
            = 0;
                        
            if( isNotNULL(m_Data) ) 
                        {
                            iRet 
            = getOriData()->Capacity;
                        }
                        
            return iRet;
                    }
                    
            ///取當(dāng)前字符串的長(zhǎng)度
                    XInt getLength() const
                    {
                        XInt iRet 
            = 0;
                        
            if( isNotNULL(m_Data) )
                        {
                            iRet 
            = getOriData()->Length;
                        }
                        
            return iRet;
                    }
            這個(gè)字符串沒(méi)有考慮內(nèi)存節(jié)省的方式而使用COW(改變的時(shí)候?qū)?,我個(gè)人覺(jué)得沒(méi)有必要,這樣做會(huì)引入線(xiàn)程安全性的問(wèn)題。我用的每個(gè)字符串對(duì)象都有一個(gè)拷貝。圖省事吧,大多數(shù)的時(shí)候,不用考慮線(xiàn)程安全性的問(wèn)題。
            為了減少內(nèi)存碎片,這里內(nèi)存申請(qǐng)的大都是指定大的倍數(shù)。下面是定義:STRING_BLOCK_SIZE = 64;
                    //字符串內(nèi)的常量定義,不給外部使用的
                    enum 
                    { 
                        STRING_BLOCK_SIZE 
            = 64,                //單位塊大小
                        CHAR_SIZE = sizeof(T),                //每個(gè)字符串的大小
                        HEAD_SIZE = sizeof(SStringStruct),    //字符串頭的字節(jié)數(shù)
                        XSTRING_BASE_ENUM_FORCE_DWORD = 0x7FFFFFFF //強(qiáng)制該Enum為32位
                    };    //字符串最小內(nèi)存塊大小
            在字符的長(zhǎng)度增加的時(shí)候,會(huì)使用ensureCapacity這個(gè)函數(shù),確定當(dāng)前容量是否夠。如果不夠?qū)⒄{(diào)用expandCapacity擴(kuò)展所需要的容量。每次擴(kuò)展的容量,默認(rèn)是原來(lái)容量的2倍增長(zhǎng)。
                    ///確定裝載字符容量(會(huì)自動(dòng)增加0結(jié)尾)
                    void ensureCapacity(XInt paramCharCapacity)
                    {
                        
            if( paramCharCapacity > 0)
                        {
                            expandCapacity(paramCharCapacity 
            + 1); //增加一個(gè)字符0的位置
                        }
                    }
                ///擴(kuò)展容量
                /**
                    注意:這個(gè)函數(shù),并不會(huì)做安全檢查
                    @param [in] paramMinimumCapacity 指定的最小容量,這個(gè)容量是字符個(gè)數(shù)
                
            */
                template
            <class T,class Alloctor>
                
            void XStringBase<T,Alloctor>::expandCapacity(XInt paramMinimumCapacity)
                    ZDH_THROW(XEOutOfMemory)
                {
                    
            //ZDH_ASSERT(paramMinimumCapacity>0);
                    XInt iNowCapacity = getCapacity();
                    
            if( iNowCapacity < paramMinimumCapacity)    
                    {
                        XInt iNewCapacity 
            = paramMinimumCapacity * CHAR_SIZE + HEAD_SIZE; //取得實(shí)際所需的字節(jié)數(shù)
                        iNowCapacity *= 2;
                        
            if( iNewCapacity < iNowCapacity) iNewCapacity = iNowCapacity;
                        XInt iMod 
            = iNewCapacity % STRING_BLOCK_SIZE;
                        
            //確保申請(qǐng)的內(nèi)存為指定大小的倍數(shù)
                        if( iMod > 0 )
                        {
                            iNewCapacity 
            += (STRING_BLOCK_SIZE - iMod);
                        }
                        SStringStruct 
            * pData = (SStringStruct *)Alloctor::Alloc(iNewCapacity);
                        
            //檢查內(nèi)存是否溢出
                        if( pData == NULL )
                        {
                            
            throw XEOutOfMemory();
                        }
                        
            //設(shè)置基本屬性
                        pData->Capacity = (iNewCapacity - HEAD_SIZE) / CHAR_SIZE;
                        pData
            ->Length = getLength();
                        
            if( pData->Length > 0 ) //復(fù)制數(shù)據(jù)
                        {
                            CopyData( (T 
            *)m_Data, (T *)(pData + 1), getLength() );
                        }
                        
            else
                        {
                            
            *((T *)(pData + 1)) = 0;
                        }
                        
            //釋放原來(lái)的
                        if( m_Data != NULL )
                        {
                            Alloctor::Free(getOriData());
                        }
                        
            //開(kāi)始替換
                        m_Data = (T *)(pData+1);
                    }
                }
            這個(gè)字符串我喜歡的地方是它提供了整數(shù)轉(zhuǎn)字符串和字符串轉(zhuǎn)整數(shù)的方法。還提供了類(lèi)似printf和cat_printf格式字符串的函數(shù)。相信寫(xiě)過(guò)C和C++的朋友,應(yīng)該都喜歡用吧。用它我就不用再像C一樣考慮要給他臨時(shí)分配多少空間。另外還提供了查找函數(shù)Pos,去除空格函數(shù)Trim,大小寫(xiě)轉(zhuǎn)換函數(shù)uppercase,lowercase,替換ReplaceString,子串SubString等函數(shù)。這個(gè)字符串還重載了,[]<<等運(yùn)符串,我們可以這樣定義字符串:
            XAnsiString strTemp;
            strTemp 
            <<"hello,我是","Rex","我今年",18,"";
            也可以strTemp.printf(
            "hello %d",18);
            總之,就是為了字符串方便簡(jiǎn)單易用。
            最后,在這里,內(nèi)存分配使用的是new和delete,不存在移植的問(wèn)題。
            posted on 2010-10-25 19:52 冬瓜 閱讀(2111) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): 原創(chuàng)
            国产精品视频久久久| 久久久久亚洲国产| 久久国产精品二国产精品| 久久精品国产99久久久香蕉| 久久久久这里只有精品| 精品久久久无码人妻中文字幕| 久久精品麻豆日日躁夜夜躁| 久久国产免费| 精品一区二区久久| 老男人久久青草av高清| 91久久成人免费| 亚洲AV无码久久精品狠狠爱浪潮| 国产99久久九九精品无码| 狠狠色噜噜色狠狠狠综合久久| 93精91精品国产综合久久香蕉| 亚洲国产精品久久电影欧美| 亚洲国产成人久久一区久久| 91精品国产91久久久久久青草| 久久天天躁狠狠躁夜夜avapp| 日韩十八禁一区二区久久| 91亚洲国产成人久久精品网址| 久久精品国产亚洲av日韩| 久久经典免费视频| 久久久精品人妻无码专区不卡| 久久精品国产91久久综合麻豆自制| 国产精品99久久久精品无码 | 久久天天躁狠狠躁夜夜av浪潮 | 久久精品国产清高在天天线| 久久精品综合网| 久久亚洲精品无码VA大香大香| 久久精品一区二区三区中文字幕| 久久精品国产久精国产| 久久96国产精品久久久| 国产精品一久久香蕉国产线看| 久久久久99精品成人片试看| 久久精品天天中文字幕人妻| 2022年国产精品久久久久 | 午夜精品久久久内射近拍高清 | 国内精品久久久久久久久电影网| 久久只这里是精品66| 久久亚洲AV无码精品色午夜|