代码之家  ›  专栏  ›  技术社区  ›  yesraaj

如何实现std::string?

  •  50
  • yesraaj  · 技术社区  · 15 年前

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

    5 回复  |  直到 11 年前
        1
  •  70
  •   Raedwald    12 年前

    实际上,我使用的每一个编译器都为运行时提供了源代码——因此,无论您使用的是gcc还是msvc,您都有能力查看实现。然而,大部分或全部 std::string 将被实现为模板代码,这会使阅读变得非常困难。

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

    他谈到了4种变化:

    • 引用计数的实现(通常称为“写入时复制”)上的几个变体-当字符串对象被复制为未更改时,引用计数将增加,但实际的字符串数据不会增加。两个对象都指向相同的refcounted数据,直到其中一个对象对其进行修改,从而导致数据的“写入时复制”。这些变化包括存储refcount、锁等内容的位置。

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

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

    这两章都值得一读。

        2
  •  11
  •   Glen    15 年前

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

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

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

        3
  •  6
  •   unwind    15 年前

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

    此外,您可以查看gcc的实现,假设您已经安装了gcc。 If not, you can access their source code via SVN .std::string的大部分实现方式是 basic_string 从那里开始。

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

        4
  •  4
  •   progician    15 年前

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

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

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

    如前所述,字符串是以模板化的方式从向量功能派生出来的,因此处理多字节字符系统更容易。您可以使用typedef std::basic_string-specific_str_t;表达式和模板参数中的任意任意数据类型定义自己的字符串类型。

    我认为双方都有足够的优势和劣势:

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

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

        5
  •  3
  •   Georg Schölly Crazy Developer    15 年前

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

    STLPort 例如,一个C++标准库实现,它实现了其他方面的字符串。