【Qt】关于QStringLiteral和QLatin1String

最近在看Qt Creator源码的时候,发现代码中字符串的地方很多都用到QStringLiteral和QLatinString,就查了一下这两个是做什么用,就在这里记录一下这两个的用法。

QStringLiteral(str)

QStringLiteral是一个宏,该宏在编译时从字符串文字str中为QString生成数据。 在这种情况下,可以从中免费创建QString,并且将生成的字符串数据存储在已编译目标文件的只读段中

对于一下代码

// hasAttribute takes a QString argument

  if (node.hasAttribute("http-contents-length")) //...

将创建一个临时QString作为hasAttribute函数参数传递。 这可能会非常昂贵,因为它涉及内存分配以及将数据复制/转换为QString的内部编码

可通过使用QStringLiteral可以避免此开销

if (node.hasAttribute(QStringLiteral(u"http-contents-length"))) //...

在这种情况下,QString的内部数据将在编译时生成。 运行时不会发生任何转换或分配

使用QStringLiteral代替双引号的纯C++字符串文字可以显著加快编译时已知数据的Qstring实例的创建速度

这个是Qt文档的说明

 

QStringLiteral包含一个字符串后,就相当于一个QString,QString支持的成员函数也可以直接用

如我们常用的arg

QStringLiteral("2222%1").arg(22);

QLatin1String

许多QString的成员函数被重载以接受constchar*而不是QString。这包括复制构造函数、赋值运算符、比较运算符以及各种其他函数,如insert()、replace()和indexOf()。这些函数通常经过优化,以避免为const char*数据构造QString对象。例如,假设str是一个QString

if (str == "auto" || str == "extern"

          || str == "static" || str == "register") {

      ...

  }
if (str == QString("auto") || str == QString("extern")

          || str == QString("static") || str == QString("register")) {

      ...

  }

上面的方式比下面的要快得多,因为它不构造四个临时的QString对象和对字符数据进行深度复制

从_ASCII定义QT_NO_CAST_FROM_ASCII的应用程序无法访问QString的const char* API。为了提供一种指定Latin-1 string的有效方法,Qt提供了QLatin1String,它只是const char* 的一个非常薄的封装。使用qlat1string,上面的示例代码变成

if (str == QLatin1String("auto")

          || str == QLatin1String("extern")

          || str == QLatin1String("static")

          || str == QLatin1String("register") {

      ...

  }

这是一个较长的类型,但它提供了与上面使用const char *的代码相同的效果,并且比使用QString::fromLatin1()转换Latin-1 string更快

当将字符串传递给一个重载为QLatin1String的函数时,QLatin1String仍然比QStringLiteral更有效,并且此重载避免了对QString的转换。例如,QString::operator==()可以直接与qlatin1string进行比较

if (attribute.name() == QLatin1String("http-contents-length"))

这是Qt文档的说明

 

总结起来就是

当程序中使用双引号包含字符串

  1. 作为QString进行传值时使用QStringLiteral 对字符串进行包裹
  2. 当程序配置QT_NO_CAST_FROM_ASCII,用到QString的函数包含有QLatin1String的重载函数时,如insert()、replace()indexOf()、操作符重载等,使用QLatin1String对字符串进行包裹

对于为啥要使用QT_NO_CAST_FROM_ASCII,文档中是这样说明的

如果所有字符串都是US-ASCII或Latin-1,它使QString的使用更加方便,但是始终存在这样的风险:从const char*隐式转换来存在使用错误的8位编码完成。为了最小化这些风险,就使用QT_NO_CAST_FROM_ASCII的相关配置

这种情况我也不是很了解

最直接的方式就是只要是双引号包含的字符串都考虑使用QStringLiteral进行包裹,除了对QString ==、=、!=等运算符操作及nsert()、replace()indexOf()等函数操作情况下使用QLatin1String,其余的都用QStringLiteral,这样就不用考虑程序有没有使用QT_NO_CAST_FROM_ASCII或者存在其他编码风险了

同样的还有QByteArrayLiteral,用于包裹传QByteArray参数的情况,QLatin1Char用于包括单引号字符的情况

 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值