摘要:本文主要向大家介绍了 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+频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号