#【QT】关于QSTRINGLITERAL
和QLATIN1STRING
参考链接:
https://www.freesion.com/article/95411442212/
最近在看Qt
Creator
源码的时候,发现代码中字符串的地方很多都用到QStringLitera
l和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文档的说明
总结起来就是
当程序中使用双引号包含字符串
-
作为QString进行传值时使用QStringLiteral 对字符串进行包裹
-
当程序配置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 ==、=、!=等运算符
操作及insert()、replace()indexOf()等函数操作情况下使用QLatin1String,其余的都用QStringLiteral,这样就不用考虑程序有没有使用QT_NO_CAST_FROM_ASCII或者存在其他编码风险了
同样的还有QByteArrayLiteral,用于包裹传QByteArray参数的情况,QLatin1Char用于包括单引号字符的情况