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类的区别?那时候我不太清楚这两个类的区别,今天在看代 ...
随机推荐
- 模态推出 全屏 隐藏tabbar
SearchVC * vc = [[SearchVC alloc] init]; /* 底部向上 UIModalTransitionStyleCoverVertical // 淡入 UIMo ...
- 802.11ax前瞻4:802.11ax与HiperLan
序言 在早期wi-fi发展过程中,欧洲还出现过一个同期的无线局域网协议.HiperLan .所谓网络发展始终是"分久必合.合久必分".不管是有线网络当前SDN的引入.还是无线网络下 ...
- Atitit vue.js 把ajax数据 绑定到form表单
Atitit vue.js 把ajax数据 绑定到form表单 1.1. 使用场景:主要应用在编辑与提交场合..1 1.2. 绑定数据到form控件,可以使用jquery,不过vue.js更加简单1 ...
- su 和 su -
单纯使用su切揣到root,读取变量的方式 是non-login shell,这种方式下很多的变量都 不会改变,尤其是PATH,所以root用的很多命令都只能用绝对路径来执行,这种方式只是切换到roo ...
- How lock works?
Eliminating Synchronization-Related Atomic Operations with Biased Locking and Bulk Rebiasing http:// ...
- [Windows Azure] Windows Azure Identity
Windows Azure Identity Managing identity is just as important in the public cloud is it is on premis ...
- [DIOCP3-说明书] 关于DEMO的编译
总有些朋友问我,关于DEMO编译的一些问题,每次都回答大概都差不多,我想还是写篇说明书给大家,关于DEMO编译的步骤. [环境设定] 1.将DIOCP3\source路径添加到Delphi的搜索路 ...
- 【转帖】(一)unity4.6Ugui中文教程文档-------概要
原帖至上,移步请戳:(一)unity4.6Ugui中文教程文档-------概要 unity4.6中的一个重要的升级就是GUI ,也把它称为UGUI ,废话我不多说,大家可以百度了解一下. 虽然现在处 ...
- css基础 -文本溢出 text-overflow:ellipsis;
.className{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;} 外部结构如下是就失效了:(移动端) <a class ...
- Spark 保存文件 自定义分隔符
Spark 保存文件 调整分隔符 废话 找了半天没找到,在某个地方看到了类似的(文中说的是读取的时候指定),试了一下保存,发现也好用,详细如下. 用法 df.write.option("de ...