C/C++知识点之C++字符串类
小标 2019-01-10 来源 : 阅读 1276 评论 0

摘要:本文主要向大家介绍了 C/C++知识点之C++字符串类,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

本文主要向大家介绍了 C/C++知识点之C++字符串类,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

C/C++知识点之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(‘\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/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程