C++字符串类
好久没有写过程序,最近想学习下界面库的开发,基于directui的界面个人觉得还不错,像金山的源代码和duilib都是不错的。本人想结合二者做一个轻量级的界面库,同时又不依赖于常用的MFC、WTL等。在程序开发中字符串的使用是必须的,C++语音没有原生字符串,STL等标准库又多是模板类,如果开发DLL导出时就出现问题了。今天从WTL库里摘出来一个简单的字符串类,实现了基本功能,可在此基础上进行扩展。
头文件
struct CStringDataE
{
long nRefs;
int nDataLength;
int nAllocLength;
TCHAR* data() { return (TCHAR*)(this + ); }
};
_declspec(selectany) int rgInitData[] = { -, , , };
_declspec(selectany) CStringDataE* _atltmpDataNil = (CStringDataE*)&rgInitData;
_declspec(selectany) LPCTSTR _atltmpPchNil = (LPCTSTR)(((BYTE*)&rgInitData) + sizeof(CStringDataE));
class UI_API CUIString
{
public:
CUIString(void);
CUIString(const CUIString& stringSrc);
~CUIString(void); CUIString& operator =(const CUIString& stringSrc);
CUIString& operator =(TCHAR ch);
CUIString& operator =(LPCTSTR lpsz);
protected:
LPTSTR m_pchData; // pointer to ref counted string data
CStringDataE* GetData() const;
void Init();
BOOL AllocBuffer(int nLen);
void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData);
BOOL AllocBeforeWrite(int nLen);
void Release();
static const CUIString& PASCAL _GetEmptyString();
};
源文件
#include "stdafx.h"
#include "UIString.h"
#include "tchar.h"
#include "limits.h"
#include "assert.h"
CUIString::CUIString(void)
{
Init();
}
CUIString::CUIString(const CUIString& stringSrc)
{
assert(stringSrc.GetData()->nRefs != );
if (stringSrc.GetData()->nRefs >= )
{
assert(stringSrc.GetData() != _atltmpDataNil);
m_pchData = stringSrc.m_pchData;
InterlockedIncrement(&GetData()->nRefs);
}
else
{
Init();
*this = stringSrc.m_pchData;
}
}
// overloaded assignment
CUIString& CUIString::operator =(const CUIString& stringSrc)
{
if (m_pchData != stringSrc.m_pchData)
{
if ((GetData()->nRefs < && GetData() != _atltmpDataNil) || stringSrc.GetData()->nRefs < )
{
// actual copy necessary since one of the strings is locked
AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);
}
else
{
// can just copy references around
Release();
assert(stringSrc.GetData() != _atltmpDataNil);
m_pchData = stringSrc.m_pchData;
InterlockedIncrement(&GetData()->nRefs);
}
}
return *this;
}
CUIString& CUIString::operator =(TCHAR ch)
{
assert(!_istlead(ch)); // can't set single lead byte
AssignCopy(, &ch);
return *this;
}
CUIString& CUIString::operator =(LPCTSTR lpsz)
{
assert(lpsz!= NULL );
AssignCopy(lstrlen(lpsz), lpsz);
return *this;
}
CUIString::~CUIString(void)
{
if (GetData() != _atltmpDataNil)
{
if (InterlockedDecrement(&GetData()->nRefs) <= )
delete[](BYTE*)GetData();
}
} void CUIString::Init()
{
m_pchData = _GetEmptyString().m_pchData;
} BOOL CUIString::AllocBuffer(int nLen)
{
assert(nLen >= );
assert(nLen <= INT_MAX - ); // max size (enough room for 1 extra)
if (nLen == )
{
Init();
}
else
{
CStringDataE* pData = NULL;
assert(pData = (CStringDataE*)new BYTE[sizeof(CStringDataE) + (nLen + ) * sizeof(TCHAR)]);
if (pData == NULL)
return FALSE;
pData->nRefs = ;
pData->data()[nLen] = TEXT('\0');
pData->nDataLength = nLen;
pData->nAllocLength = nLen;
m_pchData = pData->data();
}
return TRUE;
}
CStringDataE* CUIString::GetData() const
{
assert(m_pchData != NULL);
return ((CStringDataE*)m_pchData) - ;
}
void CUIString::AssignCopy(int nSrcLen, LPCTSTR lpszSrcData)
{
if (AllocBeforeWrite(nSrcLen))
{
memcpy(m_pchData, lpszSrcData, nSrcLen * sizeof(TCHAR));//需改动
//SecureHelper::memcpy_x(m_pchData, (nSrcLen + 1) * sizeof(TCHAR), lpszSrcData, nSrcLen * sizeof(TCHAR));
GetData()->nDataLength = nSrcLen;
m_pchData[nSrcLen] = TEXT('\0');
}
} BOOL CUIString::AllocBeforeWrite(int nLen)
{
BOOL bRet = TRUE;
if (GetData()->nRefs > || nLen > GetData()->nAllocLength)
{
Release();
bRet = AllocBuffer(nLen);
}
assert(GetData()->nRefs <= );
return bRet;
}
void CUIString::Release()
{
if (GetData() != _atltmpDataNil)
{
assert(GetData()->nRefs != );
if (InterlockedDecrement(&GetData()->nRefs) <= )
delete[](BYTE*)GetData();
Init();
}
} const CUIString& CUIString::_GetEmptyString()
{
return *(CUIString*)&_atltmpPchNil;
}
欢迎吐槽
C++字符串类的更多相关文章
- Core Java 总结(字符和字符串类问题)
所有代码均在本地编译运行测试,环境为 Windows7 32位机器 + eclipse Mars.2 Release (4.5.2) 2016-10-17 整理 字符,字符串类问题 正则表达式问题 J ...
- Java:字符串类String的功能介绍
在java中,字符串是一个比较常用的类,因为代码中基本上处理的很多数据都是字符串类型的,因此,掌握字符串类的具体用法显得很重要了. 它的主要功能有如下几种:获取.判断.转换.替换.切割.字串的获取.大 ...
- Qt入门-字符串类QString
原地址:http://blog.csdn.net/xgbing/article/details/7770854 QString是Unicode字符的集合,它是Qt API中使用的字符串类. QStri ...
- 可变字符串类 StringBuilder
string类创建的字符串是不可变的(同一内存中),每更改一次,就会新开辟内存,不利于高效频繁操作. 当频繁操作同一字符串变量时,建议使用StringBuilder. 可变字符串类StringBuil ...
- Java开发知识之Java字符串类
Java开发知识之Java字符串类 一丶简介 任何语言中.字符串都是很重要的.都涉及到字符串的处理. 例如C++中. 字符串使用内存. 并提供相应的函数进行处理 strcmp strcat strcp ...
- C++自定义String字符串类,支持子串搜索
C++自定义String字符串类 实现了各种基本操作,包括重载+号实现String的拼接 findSubStr函数,也就是寻找目标串在String中的位置,用到了KMP字符串搜索算法. #includ ...
- 设计一个字符串类String(C++练习题)
要求:设计一个字符串类String,可以求字符串长度,可以连接两个串(如,s1=“计算机”,s2=“软件”,s1与s2连接得到“计算机软件”),并且重载“=”运算符进行字符串赋值,编写主程序实现:s1 ...
- JAVA字符串类
一.字符串类String1.String是一个类,位于java.lang包中2.创建一个字符串对象的2种方式: String 变量名=“值”; String 对象名=new String(“值”);3 ...
- 编码实现字符串类CNString实现运算符重载
题目描述: 编码实现字符串类CNString,该类有默认构造函数.类的拷贝函数.类的析构函数及运算符重载,需实现以下"="运算符."+"运算."[]& ...
- Problem B 字符串类(I)
封装一个字符串类,用于存储字符串和处理的相关功能,支持以下操作: 1. STR::STR()构造方法:创建一个空的字符串对象. 2. STR::STR(const char *)构造方法:创建一个字符 ...
随机推荐
- 基础爬虫,谁学谁会,用requests、正则表达式爬取豆瓣Top250电影数据!
爬取豆瓣Top250电影的评分.海报.影评等数据! 本项目是爬虫中最基础的,最简单的一例: 后面会有利用爬虫框架来完成更高级.自动化的爬虫程序. 此项目过程是运用requests请求库来获取h ...
- JavaScript中自定义函数以及文本框、radio、下拉框的值的获取,结合淘宝竞拍案例来理解。。。
淘宝竞拍案例: HTML部分代码: <form action="#" method="post"> <h2>欢迎进入淘宝竞拍</h ...
- docker部署ELK日志处理
docker环境下部署的ELK系统,日志处理,保留最近五个小时的日志 dockerlog.sh #!/bin/bash logs=`find /var/lib/docker/containers/ - ...
- 配置内核源码make menuconfig时出现 #include CURSES_LOC错误
配置内核时出现如下错误: liuxin@sunshine-virtual-machine:~/work/nfs_root/system/linux-2.6.22.6$ make menuconfig ...
- Cheatsheet: 2018 08.01 ~ 2018 10.31
Other Building the Ultimate Developer PC 3.0 - The Parts List for my new computer, IronHeart Face re ...
- 怎样求逆序对数(Inverse Number)?
#返回上一级 @Author: 张海拔 @Update: 2014-01-14 @Link: http://www.cnblogs.com/zhanghaiba/p/3520089.html /* * ...
- IO流的复习笔记
IO字节流和缓冲流 IO字节流的读取和写入 读取 import java.io.FileInputStream; import java.io.FileNotFoundException; impor ...
- Elasticsearch数据类型
Elasticsearch自带的数据类型是Lucene索引的依据,也是做手动映射调整的依据.映射中主要就是针对字段设置类型以及类型相关参数.1.JSON基础类型如下:字符串:string数字:byte ...
- MySQL数据库的备份与恢复命令
1.数据库导出SQL脚本 启动MySQL服务器 输入:mysqldump -u root -p 数据库名>生成脚本文件路径 输入登录密码,回车键 例如: $ mysql.server star ...
- JavaScript初学
今天学习了js的基础知识,自我归纳如下: 第一部分:js变量的声明和引入 js声明1-直接声明js代码块,使用<script></script> 2-引入外部声明,即创建一个 ...