【问题标题】:Inheriting and overriding functions of a std::string?继承和覆盖 std::string 的函数?
【发布时间】:2010-11-17 13:55:18
【问题描述】:

由于std::string 实际上是模板类的typedef,我该如何覆盖它?我想制作一个 UTF-8 std::string,它会返回正确的长度等等。

【问题讨论】:

    标签: c++ unicode utf-8 character-encoding


    【解决方案1】:

    如果您必须定义自己的字符串类型,那么不要从std::string 继承,而是定义自己的Character Traits 类并执行类似的操作

    typedef std::basic_string<unsigned char, utf8_traits> utf8string;
    

    另见Herb Sutter's website

    【讨论】:

    • +1 - std::stringtypedef 是有原因的,就是这样。
    • 另一方面,我不会使用 basic_string 来处理 UTF-8 序列。每当你试图操纵它时,弊大于利。
    • @Matthieu M.,这完全取决于您如何实现 Character Traits。我可以看到两个选项:要么直接将它们打包为 UTF-8 并实现state_type,要么将它们打包为 UTF-32 并在边界处转换。无论哪种方式,工作量都很大,但它保留了与 STL 算法的兼容性。
    【解决方案2】:

    不要从字符串派生

    std::string,也就是说,基本上整个 basic_string 模板都不是为了派生而设计的。已经有数以万计的文章了。它没有任何虚函数,所以没有什么可以覆盖的。你能做的最好的事情就是隐藏一些东西。最好是使用组合/聚合!也就是说,只需在您的班级中保留一个字符串类型的成员并转发呼叫!再次,只是为了确保

    不要从字符串派生

    【讨论】:

    • -1。此任务的最佳实践是提供 Character Traits 对象并实例化 std::basic_string。在这种情况下隐藏std::string 会引发char 签名问题,因为UTF-8 是一种8 位多字节编码。
    • @larsmans:没有异议 :) 我只是太专注于某个地方的某个人想到从非多态类型派生的事实 :)
    • -1。并没有真正回答这个问题。 larsman 的回答至少为前进的方向提供了一个好主意。
    • -1。我觉得这个论点没有说服力。它假定只有具有虚函数的类可以派生。如果basic_string 没有虚函数,那么指南 应该是:不要多态使用它。如果您正确记录了继承,则继承没有任何问题!
    【解决方案3】:

    在 C++ 中,从标准库容器派生通常被认为是一个错误。但是,您正在寻找的功能已经实现。看看Glib::ustring

    希望这会有所帮助!

    【讨论】:

      【解决方案4】:
      1. 你看过 ICU 吗?

      2. typedef 只是一个方便的标签。

        class foo : public bar {} ;

      当 bar 是 PT 的 typedef 时工作得很好。

      在这种情况下这可能不是一个好主意,但语言支持它。

      【讨论】:

        【解决方案5】:

        请确保您首先知道自己在做什么。您想从字符串对象返回的“正确长度”到底是多少?码点数?这并不总是与用户感知的字符数相对应。

        不管怎样,看看utf8-cpp 库,看看从 std::string 派生的另一种方法。

        【讨论】:

          【解决方案6】:

          更好的主意:创建一个与 STL 兼容的 utf8_string 容器,而不从 std::string 继承。

          【讨论】:

            【解决方案7】:

            编写一个符合并在任何情况下都能正常工作的 unicode 实现是非常困难的。我建议您使用现有的库或实现,而不是自己滚动。例如,Windows、OSX 和 Qt 都有支持 UTF-16 和其他编码字符串的库。

            【讨论】:

              【解决方案8】:

              正如其他人已经说过的那样:不要从 std::string 派生,它不是为此而设计的。

              你应该看看this article,它以如何创建不区分大小写的字符串类为例。您将看到std::basic_string 中实现的逻辑与字符类型无关,提供一些自定义char_traits 应该可以解决问题。

              【讨论】:

              • 其实我不建议这样做。几年前我这样做了,我不得不后悔这个决定。将会发生的事情是,您将不得不在整个代码库中在这种新类型和标准字符串类型之间来回转换。这不漂亮。在这里可以找到一篇详细解释的精彩文章:lafstern.org/matt/col2_new.pdf。摘要:不区分大小写与对象无关,而是与对象的使用方式有关。
              猜你喜欢
              • 2011-01-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-06-14
              • 1970-01-01
              • 1970-01-01
              • 2011-09-04
              相关资源
              最近更新 更多