如何实现std :: string?

时间:2009-09-23 13:39:09

标签: c++ string std cstring

我很想知道如何实现std :: string以及它与c字符串的区别?如果标准没有指定任何实现,那么任何带有解释的实现都会很好,它如何满足标准给出的字符串要求?

5 个答案:

答案 0 :(得分:71)

实际上我使用的每个编译器都为运行时提供了源代码 - 因此无论您使用的是GCC还是MSVC,您都有能力查看实现。但是,std::string的大部分或全部将被实现为模板代码,这可能会导致非常难以阅读。

Scott Meyer's book, Effective STL,有一章关于std :: string实现,这是对常见变体的一个不错的概述:“第15项:注意string实现中的变化”。

他谈到了4种变化:

  • 对引用计数实现的几种变体(通常称为写入时复制) - 当字符串对象未更改时,refcount会递增,但实际的字符串数据不会。两个对象都指向相同的refcounted数据,直到其中一个对象修改它,导致数据的“写入时复制”。这些变化存在于存储refcount,锁等内容的地方。

  • “短字符串优化”(SSO)实现。在此变体中,对象包含通常指向数据,长度,动态分配缓冲区大小等的指针。但是如果字符串足够短,它将使用该区域来保存字符串而不是动态分配缓冲区

此外,Herb Sutter's "More Exceptional C++"有一个附录(附录A:“不是(在多线程世界中)的优化”),讨论为什么由于同步问题,写入refcounted实现上的副本在多线程应用程序中经常出现性能问题。那篇文章也可在线获取(但我不确定它是否与书中的内容完全相同):

这两章都值得一读。

答案 1 :(得分:11)

std :: string是一个包装某种内部缓冲区的类,并提供了操作该缓冲区的方法。

C中的字符串只是一个字符数组

解释std :: string如何在这里工作的所有细微差别需要太长时间。也许看一下gcc源代码http://gcc.gnu.org,看看他们究竟是怎么做的。

答案 2 :(得分:6)

an answer on this page中有一个示例实现。

此外,假设您已安装gcc,您可以查看gcc的实现。 If not, you can access their source code via SVN。大多数std :: string是由basic_string实现的,所以从那里开始。

另一种可能的信息来源是Watcom's compiler

答案 3 :(得分:4)

字符串的c ++解决方案与c版本完全不同。第一个也是最重要的区别是当c使用ASCIIZ解决方案时,std :: string和std :: wstring使用两个迭代器(指针)来存储实际的字符串。字符串类的基本用法提供了动态分配的解决方案,因此在动态内存处理的CPU开销成本中,它使字符串处理更加舒适。

正如您可能已经知道的那样,C不包含任何内置的通用字符串类型,只通过标准库提供了几个字符串操作。 C ++提供包装功能的C和C ++之间的主要区别之一,因此它可以被视为伪造的泛型类型。

在C中你需要遍历字符串,如果你想知道它的长度,std :: string :: size()成员函数基本上只有一条指令(结束 - 开始)。只要你有内存,就可以安全地将字符串附加到另一个字符串,因此无需担心缓冲区溢出错误(以及漏洞),因为如果需要,追加会创建一个更大的缓冲区。

正如有人在此之前所说的那样,字符串是以模板化方式从向量功能派生出来的,因此更容易处理多字节字符系统。您可以使用typedef std :: basic_string specific_str_t定义自己的字符串类型;表达式与模板参数中的任何仲裁数据类型。

我认为双方都有足够的专业和反对意见:

C ++字符串优点:   - 在某些情况下更快的迭代(使用大小肯定,并且它不需要来自内存的数据来检查你是否在字符串的末尾,比较两个指针。这可能会对缓存产生影响)   - 缓冲区操作包含字符串功能,因此不必担心缓冲区问题。

C ++字符串缺点:    - 由于动态内存分配的原因,基本使用可能会对性能产生影响。 (幸运的是,你可以告诉字符串对象应该是什么原始缓冲区大小,所以除非你超过它,否则它不会从内存中分配动态块)    - 与其他语言相比,名称通常很奇怪且不一致。这对任何stl的东西都是坏事,但是你可以使用它,它会产生一些特定的C ++感觉。    - 模板的大量使用迫使标准库使用基于头的解决方案,因此它对编译时间有很大影响。

答案 4 :(得分:3)

这取决于您使用的标准库。

例如,

STLPort是一个C ++标准库实现,它实现了字符串等。