【问题标题】:C++ strings, when to use what?C++字符串,什么时候用什么?
【发布时间】:2010-11-10 08:57:03
【问题描述】:

我已经用 C++ 编写代码已经有一段时间了,我认为大多数实际使用 C++ 编写代码的人都会同意,最棘手的决定之一是从几乎令人眼花缭乱的可用字符串类型中进行选择。我最喜欢 ATLCstring 的易用性和功能,但想对可用选项进行比较研究。 我已经检查了 SO 并没有找到任何有助于选择正确字符串的内容。有些网站声明了从一个字符串到另一个字符串的转换,但这不是我们想要的。

希望根据专业、性能、可移植性(Windows、Mac、Linux/Unix 等)、易用性/功能、多语言支持(Unicode/MBCS)、缺点(如果有)和任何其他特殊情况。

我列出了到目前为止我遇到的字符串。我相信还会有更多,所以我们稍后可能会对其进行编辑以适应其他选项。请注意,我主要在 Windows 上工作,因此列表反映了相同的情况:

  1. char*
  2. std::string
  3. STL 的basic_string
  4. ATL 的CString
  5. MFC 的CString
  6. BSTR
  7. _bstr_t
  8. CComBstr

【问题讨论】:

  • 全部使用。无论如何,你最终都会把它们都放在那里,所以不要一开始就挑剔
  • 仅在使用 COM 时使用CComBstr
  • 您可以在混合中添加 ICU 字符串以进行正确的 unicode 处理。
  • 使用最适合该任务的方法?我相信他们都有优点和缺点。不过,我在这里注意到的一件事是,任何使用 char* 发布问题的人都会得到至少一个“使用 std::strings 代替”的一揽子答案。这似乎是首选解决方案。
  • @badgerr - 使用最适合该任务的方法?这就是我问这个问题的目的。可能我们都会。谢谢。

标签: c++ visual-studio string visual-c++


【解决方案1】:

并不是要抹杀你对此的热情,但实际上在一个项目中混合大量字符串类型是低效的,因此项目越大,它就越不可避免地应该选择 std::string (这是 STL char 类型的 basic_string 实例化的 typedef,而不是不同的实体),因为这是唯一的标准值语义选项。 char* 主要适用于固定大小的字符串(例如字符串文字、固定大小的缓冲区)或与 C 接口。

为什么我说它效率低下?您最终会为各种字符串参数(甚至多个参数的排列)进行不必要的模板实例化。你会发现自己调用了想要将结果加载到字符串&中的函数,然后必须在其上调用 .c_str() 并构造其他类型,进行冗余内存分配。如果使用 ASCIIZ char* 调用(例如,对某些其他字符串类型的缓冲区),即使 const std::string& 也需要一个临时字符串。当您想编写一个函数来处理特定调用者想要使用的字符串类型时,您将被推向模板,因此内联代码、更长的编译时间和重新编译依赖(有一些方法可以缓解这种情况,但它们变得复杂为了方便或自动化,它们往往需要更改各种字符串类型 - 例如,强制转换运算符或返回一些通用接口/代理对象的成员函数。

项目可能需要使用非标准字符串类型来与他们想要使用的库进行交互,但您希望尽可能减少这种情况并限制普遍性。

【讨论】:

  • 有关std::string和unicode的更多信息,请查看here
【解决方案2】:

C++ 字符串处理的遗憾故事太令人沮丧了,我无法写一篇文章,但只有几点:

  • ATL 和 MFC CString 是相同的东西(相同的代码和所有内容)。他们几年前合并了。

  • 如果您使用 _bstr_t 或 CComBstr,您可能不会使用 BSTR,除非在调用其他人的 API 时使用 BSTR。

【讨论】:

    【解决方案3】:
    • char* - 速度快,特征包括 标头中的那些,容易出错(太低级)

    • std::string - 这实际上是 std::basic_string<char, char_traits<char> > 的 typedef 一个美丽的东西 - 首先,它也很快。其次,你可以使用所有的 因为 basic_string 提供了迭代器。对于宽字符支持,还有另一个 typedef,wstring,即std::basic_string<wchar_t, char_traits<wchar_t> >。这 (basic_string) 是标准类型,因此绝对是可移植的。我会和这个一起去。

    • ATL 和 MFC 的 CString 甚至不提供迭代器,因此它们对我来说是可憎的,因为它们是 c 字符串的类包装器,而且设计得很糟糕。恕我直言

    • 不知道其他的。

    希望这部分信息有所帮助

    【讨论】:

    • 谢谢。这确实有帮助。
    【解决方案4】:

    显然,只有前三个是可移植的,因此在大多数情况下应该首选它们。如果您正在使用 C++,那么在大多数情况下您应该避免使用char *,因为原始指针和数组很容易出错。与低级 C 的接口,例如在系统调用或驱动程序中,是一个例外。 std:string 在默认情况下应该是首选,恕我直言,因为它与 STL 的其余部分非常吻合。

    再次,恕我直言,如果您需要使用例如MFC,您应该在业务逻辑中使用 std::string 的所有内容,并在您点击 WinApi 函数时与 CString 进行转换。

    【讨论】:

    • 我猜你想写不应该char *
    【解决方案5】:

    2 和 3 是一样的。 4和5也是一样的。 7 和 8 是 6 的包装。因此,可以说,该列表仅包含 C 的字符串、标准 C++ 的字符串、Microsoft 的 C++ 字符串和 Microsoft 的 COM 字符串。这给了你答案:在标准 C++ 中,使用标准 C++ 字符串 (std::string)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-24
      • 2011-03-27
      • 1970-01-01
      • 2012-02-12
      • 1970-01-01
      • 2011-09-28
      • 1970-01-01
      • 2012-08-07
      相关资源
      最近更新 更多