C++ std::string是如何实现的?

C++ std::string是如何实现的?,c++,string,std,cstring,C++,String,Std,Cstring,我很想知道std::string是如何实现的,它与c string有什么不同?如果标准没有指定任何实现,那么任何带有解释的实现都会很好地满足标准给出的字符串要求。中有一个示例实现 此外,假设已经安装了gcc,您可以查看gcc的实现。大多数std::string都是由实现的,所以从这里开始 另一个可能的信息来源是std::string是一个类,它围绕某种内部缓冲区,并提供操作该缓冲区的方法 C中的字符串只是一个字符数组 在这里解释std::string如何工作的所有细微差别将花费太长时间。也许可以

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

中有一个示例实现

此外,假设已经安装了gcc,您可以查看gcc的实现。大多数std::string都是由实现的,所以从这里开始


另一个可能的信息来源是std::string是一个类,它围绕某种内部缓冲区,并提供操作该缓冲区的方法

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


在这里解释std::string如何工作的所有细微差别将花费太长时间。也许可以看看gcc源代码,看看它们是如何做到的。

这取决于您使用的标准库


< P>是一个C++标准库实现,它实现了其他事情的字符串。

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

,有一章介绍了std::string实现,这是对常见变体的一个不错的概述:“第15项:注意
string
实现中的变体”

他谈到了4种变化:

  • ref-counted实现的几种变体(通常称为写时复制)—当字符串对象复制时保持不变,refcount会增加,但实际字符串数据不会增加。两个对象都指向相同的refcounted数据,直到其中一个对象修改它,从而导致数据的“写入时复制”。不同之处在于refcount、锁等的存储位置

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

此外,还有一个附录(附录A:“非(在多线程世界中)”讨论了为什么写时拷贝refcounted实现在多线程应用程序中经常由于同步问题而出现性能问题。这篇文章也可以在网上找到(但我不确定它是否与书中的内容完全相同):


<>这两章都值得阅读。

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

您可能已经知道,C不包含任何内置的通用字符串类型,只通过标准库提供两个字符串操作。C和C++的主要区别之一是C++提供了一个包封的功能,因此它可以被认为是伪造的泛型类型。 在C语言中,如果想知道字符串的长度,需要遍历字符串,std::string::size()成员函数基本上只是一条指令(end-begin)。只要有内存,您就可以安全地将字符串一个附加到另一个,因此无需担心缓冲区溢出错误(以及漏洞),因为如果需要,附加会创建更大的缓冲区

正如前面有人所说,字符串是从向量功能派生出来的,采用模板化的方式,因此更容易处理多字节字符系统。您可以使用typedef std::basic\u string specific\u str\t定义自己的字符串类型;模板参数中具有任意任意数据类型的表达式

我认为双方都有足够的正反两面:

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

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

您可能希望将源代码放到类似gcc的地方,看看它们是如何实现的。相关:注意(因为链接自最近的一个问题):有趣的是,GCC的写时复制实现在移动情况下的性能优于VC++短字符串优化,因为移动操作主要受对象的大小影响。“短字符串优化”通常缩写为“SSO”:我同意Scott Meyers和Herb Sutter的书中包含了大量关于字符串实现的一般信息,但他们没有确切说明哪些实现使用了哪些优化(或非优化)。如果您想知道这一点,这里有一个比较:gcc实现在这里: