QTL or STL

声明:本文由risent翻译自http://blog.codeimproved.net/2009/12/qtl-or-stl/ ,由于水平所限,任何翻译错误欢迎留言指教。

首先,讲一小段历史:当我开始用Qt来工作的的时候我有STL/Boost的背景,同时已经习惯使用STL容器和字符串。我工作的第一个Qt项目是移植一个大规模的C++系统到Linux上来,项目的方法是使用:Qt严格的局限于UI,同时STL,Boost和其他的库用在所有的事情中。

在那个时候,我甚至不知道这里还有一个QTL,同时我在任何地方漂亮的使用std::(w)string。经过从事了更多的Qt项目,我现在在任何地方使用QTL同时对这两个库拥都有了广泛的经验。我的结论是在这个比较中这里没有明显的获胜者,同时这个选择将是十分复杂的依赖于项目的类型,转换其中的一个库到另外一个往往会一起一些微妙的麻烦。

Containers

STL和Qt在容器上有着不同的哲学:

STL

  • 容器是非常参数化和追求最快的速度的
  • 对每个容器都有性能保证
  • 每一个实现都能够使用适合的copy-on-write
  • 自由,泛型函数是首选的成员函数
  • 有多个容器的实现,就像有多个标准库的实现一样
  • ..同时这些实现不是二进制兼容的,但是他们必须服从 C++标准.这包括接口和性能保证
  • 每个实现都是自由任意的去做优化,只要尊重标准
  • 提供正则迭代器
  • 在TR1中只包含了一种hash
  • 在TR1中只包含了一种动态长度数组
  • 只要有一个头文件的实现,编译器将能访问所有的代码
  • 有<aligorithm>头文件

QTL

  • 容器不是参数化的,不象默认的内存分配,?也是,这是太糟糕了
  • 帮助文档里提供了一个性能保证的列表
  • 使用copy-on-write来避免不需要的昂贵的复制
  • 为了方便提供了非常多的成员函数,比如:contains,indexOf,removeAt,takeAt,uniqueKys,startsWith等
  • 这是一个实现二进制兼容的主发行但不是主要版本,比如Qt4.5是与Qt4.9向上兼容的,但是Qt3.2.2不与Qt4.0兼容
  • Qt容器做的优化在所有的操作系统上都有效
  • 能够使用STL风格或者Java风格的迭代器
  • 包含一个hash和多个hash的实现
  • 包括QvarLengthArray
  • 不只是头文件,一些函数在建立程序时不是有效的同时他们不能备用做全局优化
  • 有<QtAlgorithm>头文件

如果你将Qt容器与Qt framework一起使用,你将会得到一些其他的优点:

  • Qt容器是默认可以由QDataStream流化的(streamable).这意味着你只需对你自定义的容器类型写一个流操作
  • 他们使用了Qt’s API的扩展。如果你使用STL容器的话,你就当然不得不做大量的转换
  • 一些信号槽连接复制他们的参数。自从Qt容器使用COW,复制他们是非常廉价的
  • 你能够使用Q_FOREACH来用Qt容器.自从Q_FOREACH做了一个目标容器的拷贝后,那么使用STL将会是有非常大开销的

我的观点是使用QTL的最大的优点是它在所有Qt支持的平台上有着相同的实现(包括二进制兼容)。一些STL实现可能低于平均水平当涉及到性能或他们可能缺少的一些功能。一些平台甚至没有STL。在另一方面,STL是非常自定义化的同时在它所有的头文件起作用。。。。就像我所说的,这里没有明确的获胜者。

Strings

当你决定采用QString来代替std::(w)string的时候,这里的几点是需要考虑的:

  • 在谈到可用性的时候QString的得分比std::basic_string高出很多
  • 它提供了Unicaode支持
  • 它存在与dll/so中,这就是说整个程序的优化是不起作用的。这个在将Qt静态连接的时候是可以工作的,但是static VS dynamic的争论是十分复杂同时这个决定将会有产生十分广泛的影响
  • 不允许字符特征的自定义或自定义内存。实际上,QString是一个正则类,而不是模板同时它能够被正向声明(forward declared).

个人观点,我经常使用QString在我使用Qt的时候。我原本使用转换帮助来避免深入Qt依赖,但是除非你的程序大部分是Qt-free的,同时使用QString和std::string是不值得的。

Not a drop in replacement

Qt容器是STL兼容的,同时他们提供迭代器来匹配STL算法库和容器接口模仿STL。另一个附加是,这里有一个STL兼容模式来允许你直接来转换STL容器当你和Qt counterpart一起工作的时候。比如:QVector::toStdVector。

然而,你不能在Qt和STL容器之间容器的交换就向替代或者类型定义那样

  • QVector::at没有做除了断言之外的范围检查
  • QList提供了基于索引的访问和更多类似于一个std::deque。 QLinkedList大概是一个接近std::list的东西
  • 在STL没有 constBegin,constEnd,constFind,等函数。你可能不太容易来应用Qt的COW的实现
  • QMap和QMultiMap接口与std::map和std::multimap不同。特别是,这里没有相同范围的函数。
  • Qt容器不能由分配者参数化

Smart pointers

来自Mokia/ex-Trolltech的Thiage Maceiro已经做了一个关于智能指针的极好的总结。如果你读完这个总结,你将会知道99%关于Qt智能指针你应该知道的东西。

我在附加一点我的经验观察:

  • 不幸的是TR1并没有广泛的传播在我所想要的这一点上同时我发现它是非常容易来用Qt共享指针代替来代替引进一个巨大的Boost依赖在一个项目中
  • QScopedPointer支持 d-ponters和自定义删除器。AFAIK,既不是scoped_tr也不是auto_ptr做的。
This entry was written by risent , posted on Sunday January 10 2010at 07:01 am , filed under C/C++, Qt and tagged , . Bookmark the permalink . Post a comment below or leave a trackback: Trackback URL.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>