60

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

4

5 回答 5

81

几乎我使用的每个编译器都为运行时提供了源代码——因此,无论您使用的是 GCC 还是 MSVC 或其他任何东西,您都可以查看实现。但是,大部分或全部都std::string将实现为模板代码,这可能会导致非常难以阅读。

Scott Meyer 的书 Effective STL有一章是关于 std::string 实现的,它很好地概述了常见的变体:“第 15 条:注意string实现中的变体”。

他谈到了4种变化:

  • 引用计数实现的几个变体(通常称为写入时复制) - 当字符串对象被原封不动地复制时,引用计数会增加,但实际的字符串数据不会。两个对象都指向相同的引用计数数据,直到其中一个对象修改它,从而导致数据的“写入时复制”。变化在于存储引用计数、锁等内容的位置。

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

此外,Herb Sutter 的“More Exceptional C++”有一个附录(附录 A:“不是(在多线程世界中)的优化”),讨论了为什么在多线程应用程序中由于同步问题而导致复制时引用计数的实现经常出现性能问题。那篇文章也可以在线获得(但我不确定它是否与书中的内容完全相同):

这两章都值得一读。

于 2009-09-23T15:15:30.207 回答
15

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

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

在这里解释 std::string 如何工作的所有细微差别将花费太长时间。也许看看 gcc 源代码http://gcc.gnu.org看看他们是如何做到的。

于 2009-09-23T13:46:21.097 回答
8

此页面上的答案中有一个示例实现。

另外,你可以看看 gcc 的实现,假设你已经安装了 gcc。如果没有,您可以通过 SVN 访问他们的源代码。大多数 std::string 是由basic_string实现的,所以从那里开始。

另一个可能的信息来源是Watcom 的编译器

于 2009-09-23T13:45:36.230 回答
5

字符串的 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++ string Cons: - due to the dynamic memory allocation stuff, the basic usage could cause impact on the performance. (fortunately you can tell to the string object what should be the original buffer size, so unless you are exceed it, it won't allocate dynamic blocks from the memory) - often weird and inconsistent names compared to other languages. this is the bad thing about any stl stuff, but you can use to it, and it makes a bit specific C++ish feeling. - the heavy usage of the templating forces the standard library to use header based solutions so it is a big impact on the compiling time.

于 2009-09-23T17:32:21.757 回答
3

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

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

于 2009-09-23T13:49:03.540 回答