Table of Contents
概要
我们知道,C++标准库(STL)提供了string(basic_string)类进行字符串操作。字符串很可能除了内存分配器(allocator)外使用最为频繁的STL类。但是C++社区对string的指责从来就没有停止过。
归纳起来,STL的string类主要有以下这些争议点:
- 接口过多且规格和其他STL容器没有达成很好的一致性。例如,string::find使用下标,而不是以iterator作为迭代位置,这和其他容器不太一样。
- 内存碎片。由于过于频繁的字符串构造、析构,导致系统的内存碎片现象严重。
- Copy -On-Write与多线程安全。string(basic_string)基于Copy-On-Write技术的原因,是因为 string的赋值被设计成为低开销的。但是一旦考虑到多线程安全问题,Copy-On-Write会把大量的时间花在锁的开销上。一些新的STL实现 (如SGI STL)放弃了基于Copy-On-Write的string实现。
我认同这些指责。字符串最好的设计,还是将string分拆为一个常字符串(std::String)和一个字符串操作类(StringBuilder)。我们的StdExt库这样做了。
理解String(BasicString)
StdExt的String(BasicString),和你以前见过的所有字符串类都不太一样。这个类比你想象的还要简单,它只有两个成员变量:
template <class _E>
class BasicString
{
const _E* m_pszBuf;
size_t m_length;
};
它区别于string(basic_string)之处在于:
- 它是一个常字符串,它永远不会试图去篡改字符串内容(m_pszBuf指向的数据)。
- 它没有析构,你可以认为其实只是一个结构体。当然,为了方便,BasicString还是有构造函数。
- 它的m_pszBuf不以nil为结束。而是由m_length成员限定字符串的长度。
- 它不维护字符串内容(m_pszBuf)的生命周期。如上所述,它没有析构,任何时刻它只是接受或者生成字符串内容,但是不负责销毁它。
最后一点非常重要,也是它的特别之处:它并不维护字符串的生命周期。这可能让你诧异:居然会有这样字符串类,它并不管理字符串的生命周期。
但是我们这样做了。而这的确给我们带来很多便利。例如:
- 赋值(复制)、子串(substr)是非常轻量的操作。Copy-On-Write技术完全是多余的。
- 可以将任意的线性容器(如std::vector、std::basic_string)临时转换为String(非常轻量)。参见下文中对String::cast方法的介绍。
为什么String类可以不管理自己的生命周期?这就是我们StdExt的内存管理变革倡导的思想了。
浏览下String类的参考手册,你注意到有这样两个构造函数:
BasicString(const value_type* pszVal, size_type cch);
template <class AllocT>
BasicString(AllocT& alloc, const value_type* pszVal, size_type cch);
这表示:第一个构造函数传入的pszVal,其生命周期比BasicString长(到BasicString析构时仍然有效)。而第二个构造函数的意思是,pszVal是一个临时有效的字符串,这个构造函数将拷贝一个pszVal字符串的副本。
为什么不支持 BasicString(const value_type* pszVal) 这样的构造?
很简单,这个构造过于危险,我不能确定你的意图是什么。
关于TempString基类
从字面意思来讲,这是一个临时字符串类。为什么它会是String(即BasicString)的基类?这其实只是实现上的需要。TempString理论上就是String(只是有特殊的生命周期),和BasicString规格一致。之所以它最后成为BasicString的基类,完全是实现上方便的考虑。
以BasicString::compare为例,我们考察以下这个函数:
int BasicString::compare(const TempString<_E> b) const;
这个函数的含义非常丰富。相当于定义了以下这一系列的函数:
int BasicString::compare(const _E& b) const;
int BasicString::compare(const _E* b) const;
int BasicString::compare(const basic_string<_E>& b) const;
int BasicString::compare(const BasicString<_E>& b) const;
int BasicString::compare(const vector<_E>& b) const;
int BasicString::compare(const BasicStringBuilder<_E>& b) const;
一个函数可抵6个函数!
你已经看到,BasicString中大量使用TempString来进行规格定义。这种方式的代码伸缩性无疑相当好。TempString的构造每增加一种线性字符串的支持,BasicString的所有相关操作即可立即支持该类型的字符串表示。
为了进一步说明这种做法的好处,我们再以字符串连接(concat)作为例子进行说明:
template <class AllocT, class _E>
BasicString<_E> concat(AllocT& alloc, TempString<_E> a1, TempString<_E> a2, ...);
concat并非是BasicString类的成员函数。而是与BasicString有密切关系的全局函数。对于STL string类,你通常被推荐用operator+或者string::append函数来进行字符串连接。如:
std::string a = std::string("Hello") + " " + "world" + "!!!";
而对应地,BasicString并无operator+或者append,它使用全局的std::concat函数进行字符串连接。如下:
std::String a = std::concat(alloc, "Hello", " ", "world", "!!!");
有意思的是,这个std::concat不只可以高效地连接任意多的字符串,而且,它还可以连接高效地连接各种线性的字符串表示,包括:char*, std::string, std::vector<char>, std::String, std::StringBuilder等。例如:
std::string hello = "Hello";
std::String space(" ", 1);
std::vector<char> excalmatory_mark(3, '!');
std::String a = std::concat(alloc, hello, space, "world", excalmatory_mark);
这其中的奥秘,全在TempString上。关于std::TempString的详细说明,参见TempString。
源码
StdExt库的工程主页:http://code.google.com/p/stdext/
参考阅读
分享到:
相关推荐
本文将详细解析两种常用的C++ `std::string`截取字符串的方法:`find`和`find_last_of`,以及如何结合使用它们来满足各种字符串处理需求。 1. `find`方法: `find`方法用于在字符串中查找指定子字符串`strSub`的第...
在C/C++编程语言中,字符串处理是非常常见的需求之一。本篇文章将详细介绍几个常用的字符串操作函数及其使用方法,包括`stpcpy`、`strcat`、`strchr`、`strcmp`、`strncmpi`、`strcpy`以及`strcspn`。 #### 1. ...
std::string、char*、const char*是C++中三个不同的字符串表示方式,它们都可以转换为托管的byte数组或字符串String,但是在C++/CLI中,它们的转换方法略有不同。 一、std::string转托管byte数组或字符串 std::...
//短小字符串类 template struct TinyString { TinyString(); template<size_t K> TinyString(const TinyString<K>& str); TinyString(size_t n, char c); TinyString(const char* s, size_t n=0...
在C/C++编程中,将字符串转化成数字是一项常见的任务,尤其在处理用户输入或解析数据时。这个程序可能涉及到将表示任意进制的字符串转换为对应的整数值。以下是关于这个话题的一些详细知识点: 1. **字符串与数字的...
根据给定的文件信息,我们可以总结出以下有关“C++字符串处理系统”的详细知识点: ### 一、项目背景与目标 #### 1.1 课题描述 本项目旨在使用C++语言开发一个字符串处理系统,该系统具备多种功能,包括但不限于:...
在C++编程语言中,字符串处理是一项基本任务。在给定的题目中,我们需要实现一个功能,即输入一个字符串,并将其倒序输出。这涉及到C++中的字符串操作和字符数组的相关知识。以下是对这一主题的详细说明: 1. **...
- `c_str()`: 返回以'\0'结尾的C风格字符串指针,常用于C/C++接口交互。 - `data()`: 类似于`c_str()`,但返回的指针不保证以'\0'结束,需注意。 8. **`string_replace`示例**: `string_replace`函数通常用于在...
在处理字符串时,虽然C++标准库(STL)提供了许多内置的工具,如`std::string`类,但有时我们需要更加定制化的功能。这个"纯C++ 字符串处理函数大全源码"正是为了满足这种需求而设计的,它包含了作者自定义封装的一...
在C++编程中,`std::string`是一个非常重要的数据类型,用于处理字符串。而`format`函数通常指的是用于格式化输出的工具,类似于C语言中的`printf`或C++的`std::stringstream`。本项目提供的`std::string format`...
在C++编程语言中,字符串处理是至关重要的一个部分,涉及到很多函数和...以上是C++字符串处理的基础知识,实际编程中还会遇到更多复杂情况,如宽字符、多字节字符集、正则表达式等,这些都需要根据具体需求学习和掌握。
字符串宽度 获取字符串的可视宽度-显示字符串所需的列数 某些Unicode字符为并且使用正常宽度的两倍。 被剥离,并且不影响宽度。 有助于测量命令行输出的实际宽度。 安装 $ npm install string-width 用法 import ...
### C++字符串输入详解 在C++编程语言中,字符串处理是常见的需求之一,而C++提供了多种方式来处理字符串,其中最显著的区别在于传统的C风格字符串与C++的`std::string`类。本文旨在深入探讨C++中字符串输入的各种...
C++字符串处理大集合 在 C++ 中,字符串处理是非常重要的一部分,对于初学者来说,掌握字符串处理函数是非常必要的。下面我们将对 C++ 中的字符串处理函数进行详细的介绍。 C 语言字符串处理函数 1. 字符串长度:...
### 使用C++比较两个字符串的大小 在C++编程语言中,比较字符串是常见的操作之一。本篇文章将基于提供的代码示例,详细解释如何通过指针和`for`循环来比较两个字符串的大小。 #### 代码解读 首先,让我们详细了解...
根据给定的信息,我们可以归纳和总结出以下关于 C 语言及 C++ 中字符串处理的关键知识点: ### 一、字符串处理概述 在 C 语言及 C++ 中,字符串是一系列字符的序列,通常以空字符(`\0`)作为结束标志。处理字符串...
根据提供的信息,我们可以详细探讨几个重要的C语言字符串处理函数,这些函数是进行字符串操作的基础工具。下面我们将逐一介绍这些函数的功能、用法以及提供具体的示例代码。 ### 1. stpcpy #### 功能 `stpcpy` 函数...
10. **实际应用**:在实际开发中,C++解析JSON字符串常用于API通信、配置文件读取、日志分析等领域。 在文件"JsonParse"中,可能包含了使用C++解析JSON字符串的示例代码,包括如何导入库、创建JSON对象、解析字符串...
这篇“C++字符串完全指南”深入浅出地介绍了C++中处理字符串的方法,是初学者不可多得的学习资源。下面我们将详细探讨C++中的字符串概念、字符串操作以及如何读取字符串。 1. **C++字符串基础** 在C++中,字符串是...
在C++编程中,字符串处理是一项重要的任务,而C++字符串类`std::string`是进行文本操作的主要工具。这个类提供了丰富的成员函数,使得在C++中处理字符串变得非常方便。本文将深入探讨`std::string`类,以及如何在...