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类的区别?那时候我不太清楚这两个类的区别,今天在看代 ...
随机推荐
- iOS 基础-----关于UIView 的 frame 与 bounds
首先,对于frame 大家都很熟悉,是当前view ,相对于其父视图view 的坐标,例如: UIView *view1 = [[UIView alloc] initWithFrame:CGRectM ...
- Xilinx FPGA 的PCIE 设计
写在前面 近两年来和几个单位接触下来,发现PCIe还是一个比较常用的,有些难度的案例,主要是涉及面比较广,需要了解逻辑设计.高速总线.Linux和Windows的驱动设计等相关知识. 这篇文章主要针对 ...
- 从tableview中拖动某个精灵
virtual void registerWithTouchDispatcher(void); virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *p ...
- Fetch API 接口参考
前言 Fetch API是新的ajax解决方案,用于解决古老的XHR对象不能实现的问题,Fetch API 提供了一个获取资源的接口(包括跨域请求),任何使用过 XMLHttpRequest 的人都能 ...
- Mybatis根据配置文件获取session(多数据源)
1.config.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configura ...
- LeetCode: Convert Sorted Array to Binary Search Tree 解题报告
Convert Sorted Array to Binary Search Tree Given an array where elements are sorted in ascending ord ...
- Zabbix之Python发送邮件
前言:继前篇zabbix邮件乱码问题解决,转码后,问题是解决了,但是又发现问题,有时候告警邮件没有邮件内容,只有标题,一直没找出原因,所以就换了Python脚本发送邮件,代码如下. 使用前当然是要先安 ...
- golang前后端jwt对接
0x0 什么是jwt JWT是JSON Web Token的缩写,可以用作授权认证.传统的授权认证一般采用session,由于session存储在服务端,加大了服务端的计算量, 而且多台服务器之间存在 ...
- [转]MySQL函数大全 及用法示例
原文地址:http://blog.sina.com.cn/s/blog_4586764e0100h5ct.html 1.字符串函数ascii(str) 返回字符串str的第一个字符的ascii值( ...
- C#使用ActiveMQ实例
1. ActiveMQ消息总线简介 消息队列(Message Queue,简称MQ),从字面意思上看,本质是个队列,FIFO先入先出,只不过队列中存放的内容是message而已.主要用作不同进程.应用 ...