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]高并发场景 LVS DR +KeepAlive高可用实现及ka的persistence_timeout参数
LVS-DR+keepalived模式是一种非常经典的常用生产组合 高可用场景及LVS架构 一般都用一(负载)拖多(Server Array)方式 使用LVS架设的服务器集群系统有三个部分组成: (1 ...
- 【Unity】8.2 GUI Style和GUISkin
分类:Unity.C#.VS2015 创建日期:2016-04-27 一.自定义GUI Control 功能控件 (Functional Control) 是游戏必要的,而这些控件的外观对游戏的美感非 ...
- 使用sqoop将MySQL数据库中的数据导入Hbase
使用sqoop将MySQL数据库中的数据导入Hbase 前提:安装好 sqoop.hbase. 下载jbdc驱动:mysql-connector-java-5.1.10.jar 将 mysql-con ...
- Gradle-修改.gradle默认目录
在Windows的环境变量中新建一个环境变量设置,GRADLE_USER_HOME,值为D:\Users\shaowei\.gradle,设置完成之后,点击确定,关闭设置窗口.这个时候可以去AS中看下 ...
- FFmpeg(5)-AVStream和AVCodecParameters部分参数分析
一.AVStream AVCodecContext *codec // 已过时,使用另一个 codecpar 结构体代替. AVRational time_base // 时间基数. int64_t ...
- checkpoint and savepoint in FlinK
https://info.lightbend.com/rs/558-NCX-702/images/preview-apache-flink.pdf https://www.microsoft.com/ ...
- linux netstat 统计连接数查看
服务器上的一些统计数据 1)统计80端口连接数netstat -nat|grep -i "80"|wc -l 2)统计httpd协议连接数ps -ef|grep httpd|wc ...
- C++11 类型推导decltype
我们之前使用的typeid运算符来查询一个变量的类型,这种类型查询在运行时进行.RTTI机制为每一个类型产生一个type_info类型的数据,而typeid查询返回的变量相应type_info数据,通 ...
- Vue项目页面跳转时候的,浏览器窗口上方的进度条显示
1.安装: cnpm install --save nprogress 2.在main.js中引入: import NProgress from 'nprogress' import 'nprogre ...
- Testng生成的测试报告乱码解决办法
Testng生成的测试报告乱码解决办法 2017-06-16 1 问题描述 乱码是程序编码不统一,比如Java源代码是utf-8,编译是gbk,这时会乱码. 代码如下: org.testng.Repo ...