QString相对于std::string的优势

33

QString相对于std::string有哪些优势?普通的std::string能否存储Unicode字符?我正在尝试编写一个可以打开各种歌曲文件的程序。这些文件的名称可能是不同的语言。我听说在这种情况下使用普通字符串将无法正常工作。我想让应用程序独立于QT并重用代码,例如在Android中。你有什么建议?


4
http://www.joelonsoftware.com/articles/Unicode.html - Arafangion
这可能有助于回答你问题的一部分:https://dev59.com/XG025IYBdhLWcg3wZlLd - kenny
@Arafangion:那就是乐趣的一半了……你还应该把关于文件系统编码的所有混乱也加进来。 - 6502
5
没有人提到,QString 使用隐式共享/写时复制机制来获得良好的性能提升。 - cmannett85
4个回答

41

QString 允许您使用 Unicode 进行编程,并且具有更多有用的方法,可以很好地与 Qt 集成。正如 cbamber85 所指出的那样,它还具有更好的性能。

std::string 只是按照给定的字节存储数据,不知道任何关于编码的信息。它每个字符使用一个字节,但这对于世界上的所有语言来说是不够的。最好的方式可能是使用 UTF-8 编码存储文本,其中字符可以占据不同数量的字节,而 std::string 无法正确处理这种情况!例如,这意味着 length 方法将返回字节数而不是字符数。这只是冰山一角...


1
公平地说,std::string 也可以使用 Unicode,尽管可以承认的是,这并不意味着数据处于特定的编码中。你的意思是 QString 允许 Unicode 转换吗? - Arafangion
11
如果你想避免使用Qt的东西,为什么还在用它呢?如果你必须与Qt组件进行接口交互,使用QString会让你的生活变得更加容易。 - Joey
2
@Arafangion std::string 只是按照你提供的字节存储它们,它不知道任何关于编码的信息。(这意味着,例如,length 是字节数而不是字符数) - Oleh Prypin
12
请注意,QStringstd::string存在完全相同的问题:它的大小也是UTF-16代码点的数量,而不是字符数。 - MSalters
2
@vy32: std::wstring 更糟糕。你不知道每个字符是2个字节还是4个字节,而且它也不能保证是Unicode。至少使用 std::string,你知道每个字符是1个字节,并且你不会总是有 per-codepoint 访问 wstring(例如在Windows中,wchar_t 是2个字节)。 - Tim Čas
显示剩余7条评论

11

如果你使用Qt框架编写软件,那么最好使用QString。简单的原因是几乎所有作用于字符串的Qt函数都能接受QString类型的参数。如果你使用std::string,则可能会遇到需要进行类型转换的情况。如果你的软件完全不使用Qt,考虑使用std::string,这样可以使代码更加可移植,并且不依赖于额外的框架,用户也不需要安装额外的框架才能使用你的软件。


5
仅仅因为使用一个框架,就让这个框架库在整个代码中随处可见是不应该的。在UI边界进行转换是为了防止供应商锁定而付出的微不足道的代价。 - daramarak
5
@daramarak 您是正确的,但 Qt 不仅仅是一个 UI 框架。它还提供了各种非 UI 相关的功能,如网络、SQL、XML、脚本编程等。因此,根据您对框架的使用程度,可以做出相应的选择。 - Pankaj
请确保您永远不会想要从 UI 中分离业务逻辑并将其在其他非Qt应用程序中重用。否则,将会有很多哀号和牙 gnashing 发生。 - crobar

9
我不熟悉QString,但是std::string的一个重要优点是它是标准的。关于Unicode,使用std::string存储UTF-8没有问题;但是,根据您的需求,使用std::wstring可能更好(通常会存储UTF-16或UTF-32)。
对于复杂的Unicode操作,我建议使用ICU。但对于许多应用程序,仅存储UTF-8就足够了。

1
QString 是一个合理的中间件。它没有提供完整的 ICU 功能,但它可以执行简单的任务,如从/到 UTF-8/16/32 的转换。 - MSalters
1
遵循标准总是有优势的。将框架特定类型保存到框架使用中。我只是想知道,在Unicode与std::string的情况下,UTF-16或UTF-32字符串会带来什么优势? - daramarak
@daramarak 这取决于您在代码中如何处理字符串。std::string 实际上只是一个简单的容器,带有一些额外的函数来替换其中的一些 _字节_。它不知道字符或编码,更不用说与文本相关的任何内容了。如果您正在操作文本,则表示文本的类可能更合适。或者,作为替代方案,使用将 std::string 视为 UTF-8 文本的库。 - James Kanze
1
@MSalters 截至Qt5版本,它现在完全集成了ICU及其所有好处。而且,daramarak有人会争论说QString的行为在各个平台上更加一致,而std::string则留下了很多实现决策的空间。 - Wiz

4

从技术上讲,有一个标准字符串类来存储任何类型的字符: std::basic_stringstd::stringstd::wstring只是charwcharstd::basic_string的特化。还有专门用于UTF-16和UTF-32存储的特殊化的std::u16stringstd::u32string

无论如何,如果您必须使用Qt,则QString可能始终是比任何标准库字符串更好的选择,因为整个Qt框架都是为其设计的。


1
现在我们有了std::u16stringstd::u16string_viewQStringView,我们是否应该能够编写支持这三种类型的API,并传入{s.data(), s.size()} - Ben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接