C++ StringBuilder类
#ifndef __GTL_STRING_BUILDER_H_
#define __GTL_STRING_BUILDER_H_ /* 字符串生成模板 */ #include <stdio.h>
#include <string.h>
#include <assert.h>
#include <list>
#include <string> /*
设计方案:
一、这里的TLStringBuilder::_container用std::list而不是std::vector?
官方文档上注明除非你有一个用其他容器的好理由,通常都是使用std::vector。
优势
1. 字符串总是会附加到一个容器的末尾。std::list允许在不需要内存再分配的情况下这样做;
因为vector是使用一个连续的内存块实现的,每用一个就可能导致内存再分配。
2. std::list对顺序存取相当有利,而且在m_Data上所做的唯一存取操作也是顺序的。
劣势
1. 模板类中提供了 Revoke() 方法,该方法在 std::list 和 std::vector性能上会产生差异,
std::vector性能上会更高效(因为 vector 遍历最后一个元素肯定比 list要快)
总结:之所以选用 std::list 是因为大多数场景下用户都不会使用 Revoke() 方法,因此选用 std::list
二、TLStringBuilder到底比string优化在什么地方呢?
std::string对象执行+操作时,会创建一个新对象,而TLStringBuilder不会创建新对象,TLStringBuilder减少了创建多个临时对象的消耗
经过测试,c++中的string是在堆上创建字符串的,并非静态区中创建对象,所以并不会占用很多的内存,因为每个变量用完之后会释放的。
三、注意点
a. TLStringBuilder在多线程场景下需要加锁保护
b. 模板类型有要求(并非任意类型,这是由std::basic_string类模板决定的),与类型定义的专用化字符串类型元素的char,
wstring,为wchar_t, u16string为char16_t,和u32string为char32_t。
*/ namespace gtl
{
template <typename T>
class TLStringBuilder
{
typedef std::basic_string<T> StringType; //字符串类型
typedef std::list<StringType> ContainerType; //字符串容器类型
typedef typename StringType::size_type SizeType; //字符串长度类型
public:
//构造函数
TLStringBuilder() :_container(), _length()
{
} //构造函数
explicit TLStringBuilder(const StringType &str) :_container(), _length()
{
if (str.empty())
{
return;
} this->_container.emplace_back(str);
this->_length += str.length();
} //析构函数
~TLStringBuilder()
{
this->_container.clear();
this->_length = ;
} public:
//追加字符串
TLStringBuilder & Append(const StringType &str)
{
if (!str.empty())
{
this->_container.emplace_back(str);
this->_length += str.length();
}
return *this;
} //撤销最后的字符串
TLStringBuilder & Revoke(void)
{
if (!this->_container.empty())
{
StringType tmpStr = this->_container.back();
this->_container.pop_back();
this->_length -= tmpStr.length();
} return *this;
} //获取字符串长度
SizeType Length(void)
{
return this->_length;
} //追加字符串 换行
TLStringBuilder & AppendLine(const StringType &str)
{
static T CRLF[]{ , }; // C++ 11
StringType tmpStr; if (!str.empty())
{
tmpStr = str + CRLF;
}
else
{
tmpStr = CRLF;
} this->_container.push_back(tmpStr);
this->_length += tmpStr.length(); return *this;
} //追加换行
TLStringBuilder & AppendLine(void)
{
static T CRLF[]{ , }; // C++ 11
StringType tmpStr = CRLF; this->_container.push_back(tmpStr);
this->_length += tmpStr.length(); return *this;
} //拼接字符串(IT的类型需要是迭代器类型 inputIterator )
template<class IT>
TLStringBuilder & Add(const IT &first, const IT &last)
{
for (IT item = first; item != last; ++item)
{
this->Append(*item);
} return *this;
} //转字符串
StringType ToString(void)
{
StringType tmpStr;
unsigned char *pTmp = NULL;
unsigned int offset = ; pTmp = (unsigned char *)calloc(this->_length + , sizeof(T));
assert(pTmp); for (auto item = this->_container.begin(); item != this->_container.end(); ++item)
{
memcpy(pTmp + offset, item->c_str(), item->length());
offset += item->length();
} tmpStr = (T *)pTmp; free(pTmp);
pTmp = NULL; return tmpStr;
} private:
//禁止拷贝构造 与 赋值操作
TLStringBuilder(const TLStringBuilder &r) {};
TLStringBuilder & operator= (const TLStringBuilder &) {} private:
ContainerType _container;
SizeType _length;
};
}
C++ StringBuilder类的更多相关文章
- 字符串处理总结之二(C#StringBuilder类)
动态串StringBuilder 与String类相比,System.Text.StringBuilder类可以实现动态字符串.此外,动态的含义是指在修改字符串时,系统不需要创建新的对象,不会重复开辟 ...
- Java学习笔记 02 String类、StringBuilder类、字符串格式化和正则表达式
一.String类一般字符串 声明字符串 >>String str 创建字符串 >>String(char a[])方法用于将一个字符数组创建为String对象 >> ...
- StringBuilder类与String类的区别
String对象是不可改变的,每次使用String类中的方法时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间.在需要对字符串执行重复修改的情况下,与创建新的String对象相关的 ...
- 数据结构和算法 – 4.字符串、 String 类和 StringBuilder 类
4.1.String类的应用 class String类应用 { static void Main(string[] args) { string astring = "Now is The ...
- 【JAVA中String、StringBuffer、StringBuilder类的使用】
一.String类概述 1.String对象一旦创建就不能改变. 2.字符串常量池. 字符串常量池的特点:池中有则直接使用,池中没有则创建新的字符串常量. 例1: public class Strin ...
- java之StringBuilder类详解
StringBuilder 非线程安全的可变字符序列 .该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍).如果可能,建议优先采用该类,因为在 ...
- StringBuffer类 和 StringBuilder类
上一篇中讲解了String类的用法.那么String有什么特点呢? 字符串特点:字符串是常量,其值在创建后就不能被修改.字符串的内容一旦发生变化,就会创建一个新的对象. 代码验证字符串特点: publ ...
- Java基础——数组应用之StringBuilder类和StringBuffer类
接上文:Java基础——数组应用之字符串String类 一.StringBuffer类 StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和 ...
- java中String类、StringBuilder类和StringBuffer类详解
本位转载自http://www.cnblogs.com/dolphin0520/p/3778589.html 版权声明如下: 作者:海子 出处:http://www.cnblogs.com/dolp ...
- C#中 StringBuilder类 与 String类的区别---(转)
在找工作的时候,去了些公司,避免不了要面试和笔试.不过一般最起初的是笔试.我印象中有这样有一道题目:StringBuilder类与 String类的区别?那时候我不太清楚这两个类的区别,今天在看代 ...
随机推荐
- [svc]linux文件权限
linux中,每个文件拥有三种权限 f dir权限位最佳实战 权限 对文件的影响 对文件夹的影响 r 可读取/阅读文件的内容 可以列出目录内容,无法cd,ls -l看到文件名,属性是乱码. w 可修改 ...
- scrollReveal.js页面滚动动态效果
scrollReveal.jshttp://www.dowebok.com/134.html简介 和 WOW.js 一样,scrollReveal.js 也是一款页面滚动显示动画的 JavaScrip ...
- sql server获取时间格式
在本文中,GetDate()获得的日期由两部分组成,分别是今天的日期和当时的时间: Select GetDate() 用DateName()就可以获得相应的年.月.日,然后再把它们连接起来就可以了: ...
- HTML5学习笔记(十四):变量作用域
在JavaScript中,用var申明的变量实际上是有作用域的. 如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量: function foo() { var x ...
- Natural Language Processing 课程,文章,论文
CS224n: Natural Language Processing with Deep Learning http://cs224d.stanford.edu/syllabus.html http ...
- 服务器搭建5 Samba实现文件共享
Samba服务器工作原理 客户端向Samba服务器发起请求,请求访问共享目录,Samba服务器接收请求,查询smb.conf文件,查看共享目录是否存在,以及来访者的访问权限,如果来访者具有相应的权限, ...
- 使用CountDownTimer实现倒计时功能
// 倒计时60s new CountDownTimer(60000, 1000) { @Override public void onTick(long millisUntilFinished) { ...
- Asp.Net时间方法大全
DateTime dt = DateTime.Now; //当前时间 DateTime startWeek = dt.AddDays(- Convert.ToInt32(dt.DayOfWeek.To ...
- curl传输文件实例
curl -H "Authorization:Bearer 5d719398-4230-44c7-b88b-f280b6a8d070" -H "Accept: appli ...
- s3c2440——实现裸机的简易printf函数
在单片机开发中,我们借助于vsprintf函数,可以自己实现一个printf函数,但是,那是IDE帮我们做了一些事情. 刚开始在ARM9裸机上自己写printf的实现的时候,包含对应头文件也会提示vs ...