前言:

Qt中提供了一系列的基于模板的容器类,这些类被用来存储指定类型的元素。例如,你需要一个可变长的QString的数组,你可以使用QVector<QString>, 相对于STL容器,Qt中这些容器类都是轻量级的,更安全,更容易使用,他们都是可重入的,更优化的性能,更低的内存消耗,最小的代码膨胀。你可以通过两种方式遍历容器中的元素,一种就是Java风格的,这种方式的迭代器易于使用,提供了比较上层的功能,另外一种是STL风格,它提供了一种更轻量级,效率更高的方式, 可以同Qt和STL中的算法联合使用,更为强大。




(一)QVector

QVector<T>,是Qt对所有数组的封装,比如我们想要一个int类型数组,我们原先会写int array[10],我们在Qt里可以写QVector   array(10)

赋值的时候,我们依然可以照旧array[5]=4;想获取某一项的值也还可以array[9],也就是说,原来的特性我们还可以用。

那么QVector有什么好处呢?

我们可以用count函数获知数组中有多少个元素,方便遍历

原先我们必须预定义好大小,而用QVector我们虽然最好也先定义好大小,但是预先不定义也可以。

我们可以使用append函数或者<<操作符来在数组最后端添加元素而不用担心溢出问题。

比如:

#include

   ...    

void someFunction()    

{        

        QVector strArray;        

        strArray.append("Hello");        

        strArray<<"World!";        

        strArray<<"也可以一行"<<"加多个元素"<<"这里一次加了3个";       

        //现在strArray总共有5个字符串元素,strArray.count()==5    

}    

... 

当我们想要在某一项前面插入元素时,我们可以使用insert,比如strArray.insert(1,"我在Hello与World之间");


 

(二)QLinkedList

QLinkedList<T> 基于链表实现,元素存储空间不连续,提供基于index的对元素的快速访问,有较多插入操作,删除时建议使用。 类似于QList,但是一般通过迭代器访问元素,而不是index。

QLinkedList<QString>list;

list.append(“abc”);

list.append(“def”);

QLinkedList<QString>::iteratori = list.find(“abc”);

list.insert(I,“ghi”);


 

(三)QList

QList<T>是Qt的一种泛型容器类。它以链表方式存储一组值,并能对这组数据进行快速索引,还提供了快速插入和删除等操作。

详解:

QList以链表形式存储一组元素。默认为空链表,我们可以使用<<操作符添加元素:

QList<QString> list;

list << "one" <<"two" << "three"; // list: ["one","two", "three"]

对于非const链表,操作符[]返回的是该元素的引用,并且返回值可以用途左操作数。

if ( list[0] == "Bob" )

  list[0] = "Robert";

对于只读访问,可以用at()函数实现访问,at()操作比操作符[]更快,因为它不需要深度复制。

for ( int i=0; i!=list.size(); ++i )

{

   if( list.at(i) == "Jane" )

   { cout << "Found Jane atposition:" << i<< endl;}

}

QList在链表两端都预先分配了缓存,这样就使得在QList的两端插入或删除元素变得非常地快。如果需要找出某个值在链表中出现的位置,可以使用indexOf()、lastIndexOf()函数来实现。前者进行前向查找,而后者则进行反向查找。两者都会在找到匹配元素后返回该元素的索引值,没有找到匹配元素返回-1。例如:

int i = indexOf("Jane");

if ( i!=-1 )

  cout << "First occurance of Jane is at position"<< i << endl;

实例解析

QList<T> 释放内存实例详解:

1.T的类型为非指针,这时候直接调用clear()方法就可以释放了,看如下测试代码

#include <QtCore/QCoreApplication>

#include <QList>

#include <QString>

int main(int argc, char *argv[])

{

   QCoreApplication a(argc, argv);

   typedef struct _test

    {

       int id;

       QString name;

       QString sex;

   }Por_test;

   QList<Por_test>  slist;

   for (int i=0;i<100000;i++)

    {

       Por_test s;

       s.id = 1;

       s.name = QString("hello World!");

       s.sex = QString("男");

       slist.append(s);

    }

   slist.clear();

   return a.exec();

}

2.T的类型为指针的情况,这时候直接调用clear()方法将不能释放,先看代码

#include <QtCore/QCoreApplication>

#include <QList>

#include <QString>

int main(int argc, char *argv[])

{

   QCoreApplication a(argc, argv);

   typedef struct _test

    {

       int id;

       QString name;

       QString sex;

   }Por_test;

   QList<Por_test *>  slist;

   for (int i=0;i<100000;i++)

    {

       Por_test *s = new Por_test();

       s->id = 1;

       s->name = QString("hello World!");

       s->sex = QString("男?");

       slist.append(s);

    }

   qDeleteAll(slist);

   slist.clear();

   return a.exec();

说明当T的类型为指针时,调用clear()方法并不能释放其内存,此时void qDeleteAll ( const Container & c )方法将派上用场了。

 

我们再来看下qt助手中qDeleteAll 方法的说明

void qDeleteAll ( ForwardIterator begin,ForwardIterator end )

Deletes all the items in the range [begin,end) using the C++ delete operator. The item type must be a pointer type (forexample, QWidget *).

Example:

 QList<Employee *> list;

 list.append(newEmployee("Blackpool", "Stephen"));

 list.append(new Employee("Twist","Oliver"));

 qDeleteAll(list.begin(), list.end());

 list.clear();

Notice that qDeleteAll() doesn't remove theitems from the container; it merely calls delete on them. In the example above,we call clear() on the container to remove the items.

This function can also be used to deleteitems stored in associative containers, such as QMap and QHash. Only theobjects stored in each container will be deleted by this function; objects usedas keys will not be deleted.

void qDeleteAll ( const Container & c )

This is an overloaded member function,provided for convenience.

This is the same as qDeleteAll(c.begin(),c.end()).

注意事项

QList<T>中,如果T<=4的话,QList会直接将T存放在为其开辟的内存中,如果T>4的话,QList中存放指向T的指针。例如:存放penson类,包括姓名,移动电话,家庭电话等信息,QList<penson> contactList 使用指针是取不到期望的值,直接用contactList[i]就行,而且用成员函数at()返回的值是const,不能进行修改。

QList的值必须是可数的类型,这包含了我们常用的大多数类型。如果我们存储QWidget类型的话,应该使用QWidget *,而不是QWidget。

indexOf()和lastIndexOf()操作要求值的类型能进行“==”操作。

我们可以在调用其他函数之前先调用isEmpty()函数判断链表是否为空,以避免对空链表进行错误操作。而对于以索引值index为参数的成员函数,我们还需要判断该索引值是否位于有效范围内。

我们可以利用Q_ASSERT()或者Q_ASSERT_X()加上一些合理的信息来实现错误检测。

参考文献:http://blog.csdn.net/zuokong/article/details/9106155

 


 




Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐