STL vector 和 QT QVector的用法差别实例

1.STL与数据结构

       STL是C++里最常用的容器(但不是最好的容器)。很多人在计算机学习阶段,对计算机的数据结构课程是一塌糊涂的;这种一塌糊涂的感觉,甚至伴随着很多计算机软件工程师的长期的职业周期。当然,这其实并不能够完全怪计算机学习者,相当一部分原因是中国大学的计算机学习的教材把明明很简单的事物弄成非常复杂的事物。大学的数据结构教材,一般是张乃孝的《算法与数据结构》和严蔚敏《数据结构》;这两本教材楞是把很简单的事物搞的复杂化,以至很多人想起数据结构依然心有余悸。

        比较好的教材是侯捷先生的《STL详解》,或者 马克·艾伦·维斯 的数据结构教材。这些书的好处是:用数据结构的原理讲透,同时让学习者理解这些数据结构在软件开发中的作用。

       当然,我的总结是:数据结构这门课程的作用是,告诉计算机专业者不同数据结构的存在形式、用法和事件复杂度,从而让计算机从业者在设计程序的时候,能够具有设计思想。

      STL是C++提供的一套数据结构和算法,这套数据结构和算法,包含常见的数据结构,并具有很多通用算法。这种数据结构,带来了极大便利:       

       1)让软件工程师不再重复发明轮子,而更专注与软件产品本身;

       2)让C++工程师不再过分考虑容器的内存分配和释放问题;

       3)容器配合迭代器,创造了一种泛型和迭代编程模型,让软件工程师开始迭代模型的开发。

       其他语言,也纷纷造出自己的容器“轮子”,大量方便工程师学习的语言飞速发展。

       但STL本身,却又很大不利性。比如,内存分配一次分配过下,导致大量出入数据的时候,内存重新分配频繁,造成效率不高;STL本身,不具有太多的错误发现性,导致容器出错而不易被发现。

扫描二维码关注公众号,回复: 11498508 查看本文章

2.QT对STL的升级改造

       C++98之后,C++11对STL进行了升级改造,一定程度上弥补了STL的不足。如STL的C++11里的容器,增加了HashMap,弥补了原来STL的Map没有采用Hash这一快速数据结构的不足。

       而QT自己更是自己打造了一套自己的容器。弥补了STL容器的不足。

       QT的容器的好处体现在:增加了很多断言活范围特性,让C++的错误更容易暴露。

       下面,将会以STL的vector和QT QVector为例,介绍发现的QT容器的便利性。

3.STL vector 与 QT QVector

       STL的vector一开始分配空间,但STL的vector发生访问越界(如果vector的大小不是为0)的时候,并不会出错。STL的vector的[]操作符访问实现如下:

      // element access
      /**
       *  @brief  Subscript access to the data contained in the %vector.
       *  @param __n The index of the element for which data should be
       *  accessed.
       *  @return  Read/write reference to data.
       *
       *  This operator allows for easy, array-style, data access.
       *  Note that data access with this operator is unchecked and
       *  out_of_range lookups are not defined. (For checked lookups
       *  see at().)
       */
      reference
      operator[](size_type __n) _GLIBCXX_NOEXCEPT
      { return *(this->_M_impl._M_start + __n); }
	  

      通过*(this->_M_impl._M_start + __n)可知,如果this指针存在,_M_impl._M_start存在,该操作符并不一定出错。

      而QT的QVector则对[]操作符的使用如下:

     

template <typename T>
inline T &QVector<T>::operator[](int i)
{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::operator[]", "index out of range");
  return data()[i]; }

     可见,如果访问的元素超过QVector的方位,QVector的断言会抛出一个错误。

4.样例

         为比较两者的不同,可以实现一个样例:

      

#include<vector>
#include<QVector>
#include <QCoreApplication>
#include <QDebug>

using std::vector;

int main(int argc, char *argv[])
{
    vector<int> vTest;
    vTest.push_back(1);
    qDebug()<<vTest.capacity();

    int iTest;

    for(int i = 0; i < 256; i++)
    {
        iTest = vTest[i];
    }


    QVector<int> qvecTest;
    qvecTest.push_back(1);
    iTest = qvecTest[0];

    qDebug()<<qvecTest.capacity();

    for(int i = 0; i < 256; i++)
    {
        iTest = qvecTest[i];
    }


    QCoreApplication a(argc, argv);

    return a.exec();
}

    运行结果如下:

   

     可以得知:

     1)STL的vector最开始分配的空间是1个,而QVector开始分配的空间为4个(可见QT在空间分配上的优化);

     2)STL的vector发生超过容量本身的访问,并不一定失败(因为内存可能足够大并存在),而QVector则发生了断言错误。而显然,第二种处理方式会更好。而第一种可能会造成莫名其妙的错误,尤其是当工程师忘记vector的范围,而vector本身并不出错的时候。

5.启示

       显然,QT的容器基于STL进行了升级。如果有类似于QT的容器之类的容器,优先选择更好的容器;而如果使用STL,要知道STL这种特点,并避免这类事情发生。

猜你喜欢

转载自blog.csdn.net/wangzhezhilu001/article/details/103961430