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

            專職C++

            不能停止的腳步

              C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
              163 Posts :: 7 Stories :: 135 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(28)

            我參與的團隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            一個純C++簡陋字符串實現說明,之前是發的原代碼,結果太長。無法讓大家看清。不好意思啊。
            其實中的設計很簡單,首先是數據成員設計,只有一個指針。也就是sizeof()它的時候,為4(32位系統下),而STL的string的sizeof()是32。默認情況下,是不會配置內存的,相當于定義了一個空指針。這個指針類型是T *。之所以使用T *,是因為這樣調試的時候,可以看到該字符串內容是什么。如果你定義成void *,那就什么也看不到了。
            在XStringBase定義如下:
            * m_Data;            ///<數據指針

            一但它有數據后,它就指向字符串描述結構的字符串內容部分。在這個字符串前面,還有8個字節的字符串頭。結構體定義如下
                    ///字符串結構結構體
                    struct SStringStruct
                    {
                        XInt Length;        
            ///<尺寸
                        XInt Capacity;        ///<當前字符串的容量
                        //Data                ///<當前數據指針所在的位置
                    };
            有兩個內容,一個是當前字符串的長度。不含結尾0,一個是當前申請內存的內存大小:容量。
            通過下面的函數,取得字符定義的結構體:
            SStringStruct * getOriData() 
            {    
                
            return ((SStringStruct *)m_Data) - 1;
            }
            這樣getOriData()->Length就是字符串的長度了,getOriData()->Capacity就是它的容量了。
                    ///取當前容量
                    XInt getCapacity() const
                    {
                        XInt iRet 
            = 0;
                        
            if( isNotNULL(m_Data) ) 
                        {
                            iRet 
            = getOriData()->Capacity;
                        }
                        
            return iRet;
                    }
                    
            ///取當前字符串的長度
                    XInt getLength() const
                    {
                        XInt iRet 
            = 0;
                        
            if( isNotNULL(m_Data) )
                        {
                            iRet 
            = getOriData()->Length;
                        }
                        
            return iRet;
                    }
            這個字符串沒有考慮內存節省的方式而使用COW(改變的時候寫),我個人覺得沒有必要,這樣做會引入線程安全性的問題。我用的每個字符串對象都有一個拷貝。圖省事吧,大多數的時候,不用考慮線程安全性的問題。
            為了減少內存碎片,這里內存申請的大都是指定大的倍數。下面是定義:STRING_BLOCK_SIZE = 64;
                    //字符串內的常量定義,不給外部使用的
                    enum 
                    { 
                        STRING_BLOCK_SIZE 
            = 64,                //單位塊大小
                        CHAR_SIZE = sizeof(T),                //每個字符串的大小
                        HEAD_SIZE = sizeof(SStringStruct),    //字符串頭的字節數
                        XSTRING_BASE_ENUM_FORCE_DWORD = 0x7FFFFFFF //強制該Enum為32位
                    };    //字符串最小內存塊大小
            在字符的長度增加的時候,會使用ensureCapacity這個函數,確定當前容量是否夠。如果不夠將調用expandCapacity擴展所需要的容量。每次擴展的容量,默認是原來容量的2倍增長。
                    ///確定裝載字符容量(會自動增加0結尾)
                    void ensureCapacity(XInt paramCharCapacity)
                    {
                        
            if( paramCharCapacity > 0)
                        {
                            expandCapacity(paramCharCapacity 
            + 1); //增加一個字符0的位置
                        }
                    }
                ///擴展容量
                /**
                    注意:這個函數,并不會做安全檢查
                    @param [in] paramMinimumCapacity 指定的最小容量,這個容量是字符個數
                
            */
                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; //取得實際所需的字節數
                        iNowCapacity *= 2;
                        
            if( iNewCapacity < iNowCapacity) iNewCapacity = iNowCapacity;
                        XInt iMod 
            = iNewCapacity % STRING_BLOCK_SIZE;
                        
            //確保申請的內存為指定大小的倍數
                        if( iMod > 0 )
                        {
                            iNewCapacity 
            += (STRING_BLOCK_SIZE - iMod);
                        }
                        SStringStruct 
            * pData = (SStringStruct *)Alloctor::Alloc(iNewCapacity);
                        
            //檢查內存是否溢出
                        if( pData == NULL )
                        {
                            
            throw XEOutOfMemory();
                        }
                        
            //設置基本屬性
                        pData->Capacity = (iNewCapacity - HEAD_SIZE) / CHAR_SIZE;
                        pData
            ->Length = getLength();
                        
            if( pData->Length > 0 ) //復制數據
                        {
                            CopyData( (T 
            *)m_Data, (T *)(pData + 1), getLength() );
                        }
                        
            else
                        {
                            
            *((T *)(pData + 1)) = 0;
                        }
                        
            //釋放原來的
                        if( m_Data != NULL )
                        {
                            Alloctor::Free(getOriData());
                        }
                        
            //開始替換
                        m_Data = (T *)(pData+1);
                    }
                }
            這個字符串我喜歡的地方是它提供了整數轉字符串和字符串轉整數的方法。還提供了類似printf和cat_printf格式字符串的函數。相信寫過C和C++的朋友,應該都喜歡用吧。用它我就不用再像C一樣考慮要給他臨時分配多少空間。另外還提供了查找函數Pos,去除空格函數Trim,大小寫轉換函數uppercase,lowercase,替換ReplaceString,子串SubString等函數。這個字符串還重載了,[]<<等運符串,我們可以這樣定義字符串:
            XAnsiString strTemp;
            strTemp 
            <<"hello,我是","Rex","我今年",18,"";
            也可以strTemp.printf(
            "hello %d",18);
            總之,就是為了字符串方便簡單易用。
            最后,在這里,內存分配使用的是new和delete,不存在移植的問題。
            posted on 2010-10-25 19:52 冬瓜 閱讀(2111) 評論(0)  編輯 收藏 引用 所屬分類: 原創
            亚洲日韩欧美一区久久久久我| 久久香综合精品久久伊人| 无码人妻久久一区二区三区免费 | 69SEX久久精品国产麻豆| 一日本道伊人久久综合影| 久久精品国产亚洲Aⅴ香蕉| 国产精品久久久久久久久| 久久97精品久久久久久久不卡| 久久精品中文字幕久久| 99久久精品国产一区二区| 国产成人精品久久亚洲高清不卡 | 久久久久久狠狠丁香| 国产免费福利体检区久久| 精品国产青草久久久久福利| 久久影院亚洲一区| 国内精品久久久久影院亚洲| 99久久国产宗和精品1上映| 久久久久久国产精品无码超碰| 久久久久高潮毛片免费全部播放 | 国产精品久久久久AV福利动漫| 久久精品国产亚洲AV电影| 国产精品xxxx国产喷水亚洲国产精品无码久久一区| 久久人人爽人人爽人人AV | 久久国产高清字幕中文| 久久毛片免费看一区二区三区| 无码八A片人妻少妇久久| 久久er99热精品一区二区| 国产日韩久久久精品影院首页| 亚洲国产成人乱码精品女人久久久不卡| 久久人人爽人人爽AV片| 久久国产精品成人影院| 久久毛片免费看一区二区三区| 亚洲综合伊人久久综合| 热久久国产精品| 久久亚洲国产精品五月天婷| 国内精品久久久久久99| 久久露脸国产精品| 久久99国产精一区二区三区| 免费精品国产日韩热久久| 久久精品人人做人人爽电影| 久久久久国产精品人妻|