• 一个月前尝试写了一篇关于QStringLiteral,存盘时MoinMoin罢工了。吸取一点经验,还是写成短篇吧

可是,可是,QString不就是简简单单一个字符串么?能有什么可谈的。真的么...

(本文范围:Qt4)

字符串比较

如果翻看Qt的源码,或者Qt的(正规一点)第三方库,我们很少看到这种代码:

//QString myString
if (myString == "dbzhang800") {
}

取而代之的是

if (myString == QLatin1String("dbzhang800")) {
}

为什么不使用前者?

为什么?

  • QT_NO_CAST_FROM_ASCII

熟悉这个宏的,应该清楚,一旦定义之后,前者将无法通过编译。

  • 同样,下列代码也无法通过编译。
QString s = "China";
QString s2("China");

为什么?续

  • 其实,即使不考虑 QT_NO_CAST_FROM_ASCII,前面的两个比较操作仍然可能会有性能区别。(特别在国内!)

在国内,很多新手喜欢使用

QTextCodec::setCodecForCStrings()

但是大家一般很少考虑到:该语句会直接影响到字符串比较操作的性能

if (myString == "dbzhang800") {
}

??看似完全没什么联系嘛?

答案

看看Qt4是怎么做的(为了清晰起见,进行了删减)。

#ifndef QT_NO_CAST_FROM_ASCII
inline bool QString::operator==(const char *s) const
{
if (QString::codecForCStrings)
return (s1 == QString::fromAscii(s2));
return (*this == QLatin1String(s2));
}
#endif

可是,此处用QLatin1String和QString又有什么区别?

QLatin1String

Manual 中如是说

The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.

Latin1? 看来这个东西,对国内用户也没有多大用,简单说说好了。

我们知道,QString内部存储的是 utf16 字符串。于是

QString s = "dbzhang800";

这些一个简单的10个字符的字符串,至少需要在堆上申请20个字节的存储空间。对于程序中大量使用的单字节Latin1字符来说,这还真的有点浪费。

那么 QLatin1String 是怎么做的,是少申请了一些存储空间么?

确实少了不少:这种"..."字符串本身不就在常用区么?

QLatin1String("dbzhang800");

所以,只需要直接存储它的指针的就够了

class QLatin1String
{
public:
QLatin1String(const char *s) : chars(s) {}
private:
const char *chars;

只是,这还不是最优的...

QLatin1Literal

如果仔细看QString的Manual的话,你应该注意到这个东西的存在。可是这个东西又是干嘛的?和 QLatin1String 有什么瓜葛?

额,...

  • 这是一个私有类,【从Qt4.6开始出现,从Qt5.0开始消失(变成了QLatin1String的别名)】
  • 与QLatin1String的最大区别是:它在构造时直接获取字符串的长度,而QLatin1String只保存一个指针。
class QLatin1Literal
{
public:
template <int N>
QLatin1Literal(const char (&str)[N])
: m_size(N - 1), m_data(str) {} private:
const int m_size;
const char * const m_data;

对比下面的两种用法:

QString type = "long";
QLatin1String("vector<") + type + QLatin1String(">::iterator")

QString type = "long";
QLatin1Literal("vector<") + type + QLatin1Literal(">::iterator")

后者的好处就是,不用调用strlen()来获取latin1字符串的长度。

为何在Qt5中消失了呢?

因为Qt5中引入了全新的 QStringLiteral,而且估计大家会比较喜欢这个东西。毕竟可以用于中文嘛。

一个问题是,在Qt5自身的源码中,何时使用QStringLiteral,何时使用QLatin1String,有时特别让人纠结。因为

QStringLiteral("dbzhang800");
QLatin1String("dbzhang800");

前者占用的常量区比较多,程序体积会稍微大一点。(但对于中文来说,完全没有这个问题)

QString内部不是存储的utf16字符串么?而QStringLiteral就是编译期直接生成utf16字符串。(当然,需要编译器的支持)

参考

QString 乱谈(1)的更多相关文章

  1. [转载]QString 乱谈(3)-Qt5与中文

    原文地址http://blog.csdn.net/dbzhang800/article/details/7542672?reload 两个月前,简单写过QTextCodec中的setCodecForT ...

  2. QString 乱谈(3)-Qt5与中文

    原文请看:http://blog.csdn.net/dbzhang800/article/details/7542672 两个月前,简单写过QTextCodec中的setCodecForTr等终于消失 ...

  3. QString乱谈(2)

    长期以来,很多人都清楚,一旦C++源码中直接使用了中文,这样的源码想要跨平台(I18N)会非常困难. 随着: Windows下:MSVC2010成为主流 Linux下:GCC升级到4.6 C++中的中 ...

  4. 微软ASP.NET技术“乱谈”

    微软ASP.NET技术“乱谈” 2014新年了,顺手写的一点文字,主要谈谈我对当前微软ASP.NET技术的看法,比较随意,大伙儿随便看看吧. 1 当前微软Web平台技术全貌 从2002年发布.NET ...

  5. C++矢量图形库系列(1)——矢量图形库乱谈(转)

    转自:http://blog.sina.com.cn/s/blog_4265e1760100lg03.html 本系列篇章的主要内容是讲解矢量图形库的编译.开发和使用.并不对他们周边的内容做过多的描述 ...

  6. 优测优社区干货精选|老司机乱谈编辑器之神——vim

    文 / 腾讯 吴双 前言 优测小优 有话说: 腾讯优测只有应用测试大神?不不不,我们还有各种研发大牛! *** vim 是一种信仰,我自从2004年有了这个信仰,已经12个年头了.本文介绍了学习vim ...

  7. [转]vnpy乱乱谈 02架构

    vnpy乱乱谈 02架构 转自:http://101.132.65.227/?p=51 听到架构这个词先不要害怕. 其实这部分内容还是挺简单的. 一般而言, 一个交易系统我们可以简单的分成输入, (系 ...

  8. JIT-动态编译与AOT-静态编译:java/ java/ JavaScript/Dart乱谈

    C 和 C++ 之类的编译语言性能远超Java,但是生成的代码只能在有限的几种系统上执行,这就有了Java的存在基础(JVM-跨平台) 早期 Java 运行时所提供的性能级别远低于 C 和 C++ 之 ...

  9. 乱谈Qt事件循环嵌套

    本文旨在说明:QDialog::exec().QMenu::exec()等开启的局部事件循环,易用的背后,还有很多的陷阱... 引子 Qt 是事件驱动的,基本上,每一个Qt程序我们都会通过QCoreA ...

随机推荐

  1. oracle 计算时间差

    1.计算时间差(相隔星期,天数,小时,分钟,秒) SELECT TO_CHAR(date1,'MMDDYYYY:HH24:MI:SS') date1, TO_CHAR(date2,'MMDDYYYY: ...

  2. 算法总结之 在数组中找到出现次数 > N/K的数

    题目1 给定一个整型数组arr,  打印其中出现次数大于一半的数, 如果没有这样的数,打印提示信息 进阶 给定一个整型数组arr, 再给定一个整数K, 打印所有出现次数大于 N/K的数,如果没有这样的 ...

  3. HDFS数据完整性

    数据完整性 Hadoop用户肯定都希望系统在存储和处理数据时不会丢失或损坏任何数据.尽管磁盘或网络上的每个I/O操作不太可能将错误引入自己正在读/写的数据中,但是如果系统中需要处理的数据量大到Hado ...

  4. 几招教会你解决网站出现DNS域名解析错误的困扰!

    DNS解析就是把你的域名解析成一个ip地址,服务商提供的dns解析就是能够将你的域名解析成相应ip地址的主机.这就是DNS域名解析. DNS解析出现错误,一般是我们把一个域名解析成一个错误的IP地址, ...

  5. mac 下面配置gradle

    最近刚开始用gradle,先向大家介绍一下怎么配置gradle的环境变量吧: 1.下载最新安装包gradle-xxx-all.zip:http://www.gradle.org,并解压到/Users/ ...

  6. Navicat 导入Excel与增加主键

    1.当你需要导入某Excel文件时,你必须把这个lxsl文件用Excel先打开(与其他软件的导入有点不太,其他会报错已占用之类的) 2.设置主键 当你打开你导入的Excel文件时,会显示无主键,需要你 ...

  7. js轮训

    Later.js,一个独立的JavaScript类库,提供了循环事件触发的高级应用,可以为项目替换以上两种方法. 通常,我们要完成复杂的时间预定,需要大量的if...else语句.Later.js提供 ...

  8. dom 兼容性问题1_节点部分

    AS : ECMAScript xml . html js组成: 1,ECMAScript : 是Javascript的核心标准.同时也是一个解释器. 2,DOM: document object m ...

  9. Memcache简介 & 内存分配机制

            关于这个东西里面到底应该存放数据网上一直有很多种说法,有的说sql进行md5之后作为键值,结果作为内容存放,也有人说按照业务逻辑错放,反正是炒的不亦乐乎.        本人经过将近2 ...

  10. Xcode 查找 TODO 清单

    在 Xcode 中按 Shift+Command+F,显示在项目中查找窗口,选择按正则表达式查找(Find > Regular Expression): TODO:  //\s*\bTODO\s ...