#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类的更多相关文章

  1. 字符串处理总结之二(C#StringBuilder类)

    动态串StringBuilder 与String类相比,System.Text.StringBuilder类可以实现动态字符串.此外,动态的含义是指在修改字符串时,系统不需要创建新的对象,不会重复开辟 ...

  2. Java学习笔记 02 String类、StringBuilder类、字符串格式化和正则表达式

    一.String类一般字符串 声明字符串 >>String str 创建字符串 >>String(char a[])方法用于将一个字符数组创建为String对象 >> ...

  3. StringBuilder类与String类的区别

    String对象是不可改变的,每次使用String类中的方法时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间.在需要对字符串执行重复修改的情况下,与创建新的String对象相关的 ...

  4. 数据结构和算法 – 4.字符串、 String 类和 StringBuilder 类

    4.1.String类的应用 class String类应用 { static void Main(string[] args) { string astring = "Now is The ...

  5. 【JAVA中String、StringBuffer、StringBuilder类的使用】

    一.String类概述 1.String对象一旦创建就不能改变. 2.字符串常量池. 字符串常量池的特点:池中有则直接使用,池中没有则创建新的字符串常量. 例1: public class Strin ...

  6. java之StringBuilder类详解

    StringBuilder 非线程安全的可变字符序列 .该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍).如果可能,建议优先采用该类,因为在 ...

  7. StringBuffer类 和 StringBuilder类

    上一篇中讲解了String类的用法.那么String有什么特点呢? 字符串特点:字符串是常量,其值在创建后就不能被修改.字符串的内容一旦发生变化,就会创建一个新的对象. 代码验证字符串特点: publ ...

  8. Java基础——数组应用之StringBuilder类和StringBuffer类

    接上文:Java基础——数组应用之字符串String类 一.StringBuffer类 StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和 ...

  9. java中String类、StringBuilder类和StringBuffer类详解

    本位转载自http://www.cnblogs.com/dolphin0520/p/3778589.html  版权声明如下: 作者:海子 出处:http://www.cnblogs.com/dolp ...

  10. C#中 StringBuilder类 与 String类的区别---(转)

      在找工作的时候,去了些公司,避免不了要面试和笔试.不过一般最起初的是笔试.我印象中有这样有一道题目:StringBuilder类与 String类的区别?那时候我不太清楚这两个类的区别,今天在看代 ...

随机推荐

  1. struts2(五) s标签和国际化

    坚持就是胜利. --WH 一.s标签 在struts-2.3.15.1/docs/WW/docs/tag-reference.html下,就有着struts2所有标签的参考文献,只能看看其中比较常用的 ...

  2. node调试的两种方法

    刚开始学node.js的时候,一直在用node-inspector,虽然很麻烦,但聊胜于无.后面公司牛人推荐使用node-webkit,就再也没用过node-inspector.再后来node.js版 ...

  3. FLINK 设计文档

    https://cwiki.apache.org/confluence/display/FLINK/Apache+Flink+Home https://cwiki.apache.org/conflue ...

  4. 安全管理中心(SOC)引导企业信息安全建设的思路

    SOC即企业安全管理中心,该模型可帮助企业信息安全人员在进行安全建设方面提供整体性的参考.如下所示,以下模型分为数据采集部分收集了各类设备及日志等数据,这些数据收集到了以后提供给SOC安全管理中心,而 ...

  5. ashx页面返回json字符串|jQuery 的ajax处理请求的纠结问题

    纠结,整了半天的jquery的ajax请求数据. 遇到的问题: 1 ajax方法一直进入error方法里,进入到请求的.ashx页面.这个问题,我未找到是什么原因.反正我使用了一下的代码,就好了. $ ...

  6. python(56):正则表达式积累

    来源:http://www.runoob.com/python/python-reg-expressions.html re.match函数 re.match 尝试从字符串的起始位置匹配一个模式,如果 ...

  7. [整理]Unity3D游戏开发之Lua

    原文1:[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我地博客地址是blog.csdn.net/qinyuanpei.如果 ...

  8. 【Linux技术】Windows与Linux系统下的库·初探

    库的定义  库文件是一些预先编译好的函数的集合,那些函数都是按照可再使用的原则编写的.它们通常由一组互相关联的用来完成某项常见工作的函数构成,从本质上来说库是一种可执行代码的二进制形式,可以被操作系统 ...

  9. django —— Celery实现异步和定时任务

    1. 环境 python==2.7 djang==1.11.2 # 1.8, 1.9, 1.10应该都没问题 celery-with-redis==3.0 # 需要用到redis作为中间人服务(Bro ...

  10. 【神经网络】BP算法解决XOR异或问题MATLAB版

    第一种 %% %用神经网络解决异或问题 clear clc close ms=4;%设置4个样本 a=[0 0;0 1;1 0;1 1];%设置输入向量 y=[0,1,1,0];%设置输出向量 n=2 ...