码迷,mamicode.com
首页 > 编程语言 > 详细

C++字符串类

时间:2016-04-23 21:29:42      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:

    好久没有写过程序,最近想学习下界面库的开发,基于directui的界面个人觉得还不错,像金山的源代码和duilib都是不错的。本人想结合二者做一个轻量级的界面库,同时又不依赖于常用的MFC、WTL等。在程序开发中字符串的使用是必须的,C++语音没有原生字符串,STL等标准库又多是模板类,如果开发DLL导出时就出现问题了。今天从WTL库里摘出来一个简单的字符串类,实现了基本功能,可在此基础上进行扩展。

  头文件

 1 struct CStringDataE
 2 {
 3     long nRefs;    
 4     int nDataLength;
 5     int nAllocLength;
 6     TCHAR* data()    {        return (TCHAR*)(this + 1);    }
 7 };
 8 _declspec(selectany) int rgInitData[] = { -1, 0, 0, 0 };
 9 _declspec(selectany) CStringDataE* _atltmpDataNil = (CStringDataE*)&rgInitData;
10 _declspec(selectany) LPCTSTR _atltmpPchNil = (LPCTSTR)(((BYTE*)&rgInitData) + sizeof(CStringDataE));
11 class UI_API CUIString
12 {
13 public:
14     CUIString(void);
15     CUIString(const CUIString& stringSrc);
16     ~CUIString(void);
17 
18     CUIString& operator =(const CUIString& stringSrc);
19     CUIString& operator =(TCHAR ch);
20     CUIString& operator =(LPCTSTR lpsz);
21 protected:
22     LPTSTR m_pchData;   // pointer to ref counted string data
23     CStringDataE* GetData() const;
24     void Init();
25     BOOL AllocBuffer(int nLen);
26     void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData);
27     BOOL AllocBeforeWrite(int nLen);
28     void Release();
29     static const CUIString& PASCAL _GetEmptyString();
30 };

源文件

  1 #include "stdafx.h"
  2 #include "UIString.h"
  3 #include "tchar.h"
  4 #include "limits.h"
  5 #include "assert.h"
  6 CUIString::CUIString(void)
  7 {
  8     Init();
  9 }
 10 CUIString::CUIString(const CUIString& stringSrc)
 11 {
 12     assert(stringSrc.GetData()->nRefs != 0);
 13     if (stringSrc.GetData()->nRefs >= 0)
 14     {
 15         assert(stringSrc.GetData() != _atltmpDataNil);
 16         m_pchData = stringSrc.m_pchData;
 17         InterlockedIncrement(&GetData()->nRefs);
 18     }
 19     else
 20     {
 21         Init();
 22         *this = stringSrc.m_pchData;
 23     }
 24 }
 25 // overloaded assignment
 26 CUIString& CUIString::operator =(const CUIString& stringSrc)
 27 {
 28     if (m_pchData != stringSrc.m_pchData)
 29     {
 30         if ((GetData()->nRefs < 0 && GetData() != _atltmpDataNil) || stringSrc.GetData()->nRefs < 0)
 31         {
 32             // actual copy necessary since one of the strings is locked
 33             AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);
 34         }
 35         else
 36         {
 37             // can just copy references around
 38             Release();
 39             assert(stringSrc.GetData() != _atltmpDataNil);
 40             m_pchData = stringSrc.m_pchData;
 41             InterlockedIncrement(&GetData()->nRefs);
 42         }
 43     }
 44     return *this;
 45 }
 46 CUIString& CUIString::operator =(TCHAR ch)
 47 {
 48     assert(!_istlead(ch));   // can‘t set single lead byte
 49     AssignCopy(1, &ch);
 50     return *this;
 51 }
 52 CUIString& CUIString::operator =(LPCTSTR lpsz)
 53 {
 54     assert(lpsz!= NULL );
 55     AssignCopy(lstrlen(lpsz), lpsz);
 56     return *this;
 57 }
 58 CUIString::~CUIString(void)
 59 {
 60     if (GetData() != _atltmpDataNil)
 61     {
 62         if (InterlockedDecrement(&GetData()->nRefs) <= 0)
 63             delete[](BYTE*)GetData();
 64     }
 65 }
 66 
 67 void CUIString::Init()
 68 {
 69     m_pchData = _GetEmptyString().m_pchData;
 70 }
 71 
 72 BOOL CUIString::AllocBuffer(int nLen)
 73 {
 74     assert(nLen >= 0);
 75     assert(nLen <= INT_MAX - 1);   // max size (enough room for 1 extra)
 76     if (nLen == 0)
 77     {
 78         Init();
 79     }
 80     else
 81     {
 82         CStringDataE* pData = NULL;
 83         assert(pData = (CStringDataE*)new BYTE[sizeof(CStringDataE) + (nLen + 1) * sizeof(TCHAR)]);
 84         if (pData == NULL)
 85             return FALSE;
 86         pData->nRefs = 1;
 87         pData->data()[nLen] = TEXT(\0);
 88         pData->nDataLength = nLen;
 89         pData->nAllocLength = nLen;
 90         m_pchData = pData->data();
 91     }
 92     return TRUE;
 93 }
 94 CStringDataE* CUIString::GetData() const
 95 {
 96     assert(m_pchData != NULL);
 97     return ((CStringDataE*)m_pchData) - 1;
 98 }
 99 void CUIString::AssignCopy(int nSrcLen, LPCTSTR lpszSrcData)
100 {
101     if (AllocBeforeWrite(nSrcLen))
102     {
103         memcpy(m_pchData, lpszSrcData, nSrcLen * sizeof(TCHAR));//需改动
104         //SecureHelper::memcpy_x(m_pchData, (nSrcLen + 1) * sizeof(TCHAR), lpszSrcData, nSrcLen * sizeof(TCHAR));
105         GetData()->nDataLength = nSrcLen;
106         m_pchData[nSrcLen] = TEXT(\0);
107     }
108 }
109 
110 BOOL CUIString::AllocBeforeWrite(int nLen)
111 {
112     BOOL bRet = TRUE;
113     if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength)
114     {
115         Release();
116         bRet = AllocBuffer(nLen);
117     }
118     assert(GetData()->nRefs <= 1);
119     return bRet;
120 }
121 void CUIString::Release()
122 {
123     if (GetData() != _atltmpDataNil)
124     {
125         assert(GetData()->nRefs != 0);
126         if (InterlockedDecrement(&GetData()->nRefs) <= 0)
127             delete[](BYTE*)GetData();
128         Init();
129     }
130 }
131 
132 const CUIString&  CUIString::_GetEmptyString()
133 {
134     return *(CUIString*)&_atltmpPchNil;
135 }

欢迎吐槽

C++字符串类

标签:

原文地址:http://www.cnblogs.com/gushandujian/p/5425428.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!