zoukankan      html  css  js  c++  java
  • C++字符串类

        好久没有写过程序,最近想学习下界面库的开发,基于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('');
     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('');
    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 }

    欢迎吐槽

  • 相关阅读:
    catboost原理以及Python代码
    lightgbm原理以及Python代码
    stacking算法原理及代码
    python自动化之爬虫模拟登录
    python自动化之爬虫原理及简单案例
    python自动化之PDF
    input type="file"鼠标无法变小手
    typescript中类和接口的区别
    TypeScript基础类型
    微信小程序-获取input值的两种方法
  • 原文地址:https://www.cnblogs.com/gushandujian/p/5425428.html
Copyright © 2011-2022 走看看