代码之家  ›  专栏  ›  技术社区  ›  Daniel Wright

用C++设计一个字符串类

  •  5
  • Daniel Wright  · 技术社区  · 5 年前

    我需要在C++中设计(和代码,在某个时候)一个“定制”的字符串类。我想知道您是否可以让我知道任何文档和设计问题,主要是我应该知道的潜在缺陷。链接是非常受欢迎的,因为可以识别当前字符串libs(qstring、std::string和其他字符串)的问题(如果有)。

    谢谢您。

    7 回复  |  直到 14 年前
        1
  •  14
  •   Matthieu M.    14 年前

    尽管有批评,我认为这是一个有效的问题。

    这个 std::string 不是万能药。看起来好像有人从纯OO中提取了这个类,然后把它扔进C++,这可能是事实。

    建议1: 首选非成员非朋友方法

    既然这样说了,在国际化的这个时刻,我当然建议您设计一个支持 Unicode . 我说 统一码 不是 UTF-8 UTF-16 . 我认为设计一个类来包含给定编码中的数据是不合适的。您可以提供方法,然后以各种格式输出信息。

    建议2: 支持 统一码

    然后,内存分配方案上有许多点:

    • 小字符串优化:类包含为几个字符(一打或两个)预先分配的空间,因此避免为这些字符分配堆。
    • copy-on-write:不同的字符串共享一个缓冲区,这样拷贝就很便宜,当一个字符串需要修改其内容时,如果它不是唯一的所有者,它就会复制缓冲区-->问题是多线程在这里引入了开销,并且已经表明,对于一般用途的技术来说,这种开销可能会使实际的复制成本相形见绌。
    • 不变性:“新”语言,如 Java , C# Python 使用不可变字符串。把它想象成一个字符串池,所有包含“foo”的字符串都将指向同一个缓冲区。注意,这些语言支持垃圾收集,这在这里很有帮助。

    我个人会在这里选择“小字符串优化”(尽管它并不排斥其他两个),这仅仅是因为它很容易实现,而且实际上会使您受益(堆分配成本、引用问题的位置)。

    另外两种技术在面对多线程时有点复杂,而且这些技术很容易出错,除非经过精心设计,否则不太可能产生任何真正的好处。

    这就是我最后的建议:

    建议3: 不要在尝试多线程支持时实现内部锁定

    当在单线程上下文中使用时,它将减慢类的速度,并且不会产生像在多线程上下文中使用时那样多的好处。

    最后,通过浏览现有的代码,您可能会找到适合自己口味的东西(或获得一些提示)。但我不保证展示“平滑”的界面:

        2
  •  3
  •   Philip Potter    14 年前

    Effective STL 作者Scott Meyers对可能性进行了一些有趣的讨论 std::string 实现技术,尽管它涵盖了相当高级的问题,如写时复制和引用计数。

        3
  •  2
  •   ChrisW    14 年前

    根据“自定义”是什么(例如自定义分配器),您可以通过std::basic_string类的模板参数来执行此操作。

        4
  •  2
  •   Kirill V. Lyadvinsky    14 年前

    Herb Sutter在 GotW #29 . 你可以先用它。

        5
  •  1
  •   Martin Ba    14 年前

    从通用的角度来看,“新”字符串类理想地结合了std::string、cstring、qstring和其他方面的优点。随机数点:

    • 由于实现非常具体,MFCCString支持在类似printf的函数中使用它。 如果 您需要或想要这个功能,我建议您购买GeorgeSheperd的书“MFCInternals”。尽管这本书是从1996年开始的。它描述了如何实现CString应该是值得的。 http://www.amazon.com/MFC-Internals-Microsoft-Foundation-Architecture/dp/0201407213/ref=sr_1_1?ie=UTF8&s=books&qid=1283176951&sr=8-1
    • 检查您的String类是否能很好地处理您将要使用它的所有接口(iostreams、windows api、printf*等)。
    • 不要追求完全的Unicode支持(如:排序规则、图形簇等),因为这意味着永远不会完成类的工作,但考虑将其作为带有转换选项的wchar-t类。
    • 考虑使从char*创建字符串对象的ctor/函数始终采用字符数组的特定编码。(在混合的UTF-8/其他字符集环境中很有用。)
    • 查看完整的cstring接口和完整的std:string接口,决定您需要什么以及可以跳过什么。
    • 看看qstring,看看另外两个错过了什么。
    • 提供对char/wchar和*
    • 考虑在数字类型中添加方便的转换函数。
    • 不要在没有完整的详细单元测试集的情况下编写字符串类!
        6
  •  0
  •   tenfour    14 年前

    世界不需要另一个字符串类。这是作业吗?如果没有,使用 std::string .

        7
  •  0
  •   bert hubert    14 年前

    std::string的问题是..你不能改变它。有时需要STD::字符串的基础知识,但不同意C++库的实现。

    例如,使用线程安全引用计数意味着大量的锁定(或者至少是锁定的操作)。另外,如果您的大多数字符串都很短(因为您知道情况会是这样),那么您可能需要一个针对该用例进行优化的字符串类。

    因此,即使您喜欢std::string API,或者至少已经学会了使用它,也有足够的空间来进行“竞争性实现”,这些实现或多或少都是工作技能。

    powerdns希望有一个,因为我们目前传递了很多DNS主机名,其中大部分可以放在一个25字节的固定缓冲区中,这将减轻许多新的/删除的压力。