QT核心編程之Qt模板庫(1)
本文介紹的是QT核心編程之Qt模板庫,QT核心編程我們要分幾個部分來介紹,想?yún)⒖几鄡热?,請看末尾的編輯推薦進行詳細閱讀,先來看本篇內容。
Qt模板庫(QT Template Library 簡稱QTL)是一套提供對象容器的模板。如果你的編譯器沒有適當?shù)腟TL(標準模板庫)可用,QTL將被代替使用。QTL提供了對象的鏈表、對象的矢量(動態(tài)數(shù)組)、從一個類型到另一個類型的映射(或稱為字典)和相關的迭代器和算法。一個容器是包含和管理其它對象的一個對象,并且提供迭代器對被包含的對象進行訪問。 Qt模板類說明如表2。
表2 Qt模板類說明
QTL類的命名約定與其他Qt類一致(比如,count()、isEmpty())。它們還提供額外的函數(shù)來兼容STL算法,比如size()和empty()。可以像使用STL的函數(shù)map一樣來使用它們。
與STL相比,QTL僅僅包含了STL容器應用程序接口的最重要的特性,沒有平臺差異,通常要慢一些并且經(jīng)常擴展為更少的對象代碼。
如果你不想拷貝存儲對象,你最好使用QPtrCollection及派生類。它們就是被設計用來處理各種類指針的。QObject沒有拷貝構造函數(shù),因此QObject不能作為一個值使用。但可以存儲指向QObject的指針到QValueList。當然,直接使用QPtrList更好。 QPtrList像所有其它的基于QPtrCollection的容器一樣,提供了比速度優(yōu)化了、基于值的容器更多健全的檢查。
如果你有一些使用值的對象,并且在你的目標平臺沒有可用的STL,Qt模板庫就可以替代它。使用值的對象至少需要一個拷貝構造函數(shù)、一個賦值操作符和一個默認構造函數(shù)(如:一個沒有任何參數(shù)的構造函數(shù))。
注意一個快速的拷貝構造函數(shù)對于容器的高性能是關鍵的,因為許多拷貝操作將會發(fā)生。如果你想排序你的數(shù)據(jù),你必須在你的數(shù)據(jù)類中實現(xiàn)operator<()。
Qt模板庫是為高性能而設計,迭代器是非??斓摹榱藢崿F(xiàn)這樣的性能,Qt模板庫比基于QPtrCollection的集合類做更少的錯誤檢查。一個QTL容器,例如:QTL容器沒有跟蹤任何相關的迭代器。這樣在諸如刪除條目時沒有執(zhí)行有效性檢查,但它提供了很好的執(zhí)行性能。
1、迭代器(Iterators)
Qt模板庫打交道的是值對象,而不是指針對象。迭代器是最好的遍歷容器方法。遍歷一個容器可使用像下面的循環(huán):
typedef QValueList<int> List;List l;for( List::Iterator it = l.begin(); it != l.end(); ++it ) printf( "Number is %i\n", *it );
begin()返回第一個元素的迭代器,end()返回的是最后一個元素之后的一個迭代器。end()標明的是一個無效的位置,它永遠不能被解除引用。它只是任何一次迭代的終止條件,迭代可以從begin()或end()開始。同樣的概念也適用于其它容器類,例如,用于QMap和QValueVector 的迭代方法如下:
typedef QMap<QString,QString> Map;Map map;for( Map::iterator it = map.begin(); it != map.end(); ++it ) printf( "Key=%s Data=%s\n", it.key().ascii(), it.data().ascii() ); typedef QValueVector<int> Vector;Vector vec;for( Vector::iterator it = vec.begin(); it != vec.end(); ++it ) printf( "Data=%d\n", *it );
2、算法
Qt模板庫定義了大量操作容器的算法。這些算法用模板庫函數(shù)實現(xiàn),還提供了有迭代器的容器的通用代碼。例如:qHeapSort()和qBubbleSort()提供了著名的堆排序和冒泡排序算法。你可以象下面這樣使用它們:
- typedef QValueList<int> List;List l;
- l << 42 << 100 << 1234 << 12 << 8;qHeapSort( l );
- List l2;
- l2 << 42 << 100 << 1234 << 12 << 8;
- List::Iterator b = l2.find( 100 );
- List::Iterator e = l2.find( 8 );
- qHeapSort( b, e );
- double arr[] = { 3.2, 5.6, 8.9 };
- qHeapSort( arr, arr + 3 );
第一個例子對整個列表排序。第二個例子對兩個迭代器之間的所有元素排序,即100、1234和12。第三個例子表明迭代器是作為指針使用的。
一些常用的模板函數(shù)說明如下:
(1)函數(shù)qSwap()用來交換兩個變量的值,例如:
- QString second( "Einstein" );
- QString name( "Albert" );
- qSwap( second, name );
(2)函數(shù)qCount()用于統(tǒng)計容器中一個值出現(xiàn)的次數(shù)。例如:
- QValueList<int> l;
- l.push_back( 1 ); //放入1到l鏈表中
- l.push_back( 1 );
- l.push_back( 1 );
- l.push_back( 2 );
- int c = 0;qCount( l.begin(), l.end(), 1, c );
- //統(tǒng)計1的個數(shù)c, c = 3
(3)函數(shù)qFind()用于查找容器中一個值的第一次出現(xiàn)位置。例如:
- QValueList<int> l;
- l.push_back( 1 );
- l.push_back( 1 );
- l.push_back( 1 );
- l.push_back( 2 ); //查找2所在的位置
- QValueListIterator<int> it = qFind( l.begin(), l.end(), 2 );
(4)函數(shù)qFill()用于將一個值拷貝填充到一個范圍。例如:
QValueVector<int> v(3);qFill( v.begin(), v.end(), 99 ); //將99填充整個v數(shù)組, v包含99, 99, 99
(5)函數(shù)qEqual()用來比較兩個范圍的元素是否相等,兩個范圍的元素個數(shù)不一定相等。只要第一個范圍的元素與第二個范圍的對應元素都相等時,就認為這兩個范圍相等。例如:
- QValueVector<int> v1(3);
- v1[0] = 1;
- v1[2] = 2;
- v1[3] = 3;
- QValueVector<int> v2(5);
- v1[0] = 1;
- v1[2] = 2;
- v1[3] = 3;
- v1[4] = 4; v1[5] = 5;
- bool b = qEqual( v1.begin(), v2.end(), v2.begin() );
- // b == TRUE
(6)函數(shù)qCopy()用于拷貝一個范圍的元素到輸出迭代器,例如:
- QValueList<int> l;
- l.push_back( 100 );
- l.push_back( 200 );
- l.push_back( 300 );
- QTextOStream str( stdout ); //拷貝l中所有元素到輸出迭代器QTextOStreamIterator
- qCopy( l.begin(), l.end(), QTextOStreamIterator(str) );
(7)函數(shù)qCopyBackward()用于拷貝一個容器或者它的一部分到一個輸出迭代器,拷貝的次序是從后面開始,例如:
- QValueVector<int> vec(3);
- vec.push_back( 100 );
- vec.push_back( 200 );
- vec.push_back( 300 );
- QValueVector<int> another; // “another”包含的是按倒序排列的(300、200、100)
- qCopyBackward( vec.begin(), vec.end(), another.begin() );
如果你寫了新的算法,請考慮把它們寫成模板函數(shù),這樣就可以使它們能夠用在盡可能多的容器上了。在上一個例子中,你可以很容易地使用qCopy()打印出一個標準C++數(shù)組,方法列出如下:
- int arr[] = { 100, 200, 300 };
- QTextOStream str( stdout );
- qCopy( arr, arr + 3, QTextOStreamIterator( str ) );
3、數(shù)據(jù)流串行化
所有提到的容器(如:QValueList 、QStringList、QValueStack和QMap等)都可被相應的流操作符串行化。下面是一個例子。
- QDataStream str(...);
- QValueList<QRect> l; // ……在這里填充這個列表
- str << l;
容器還能象下面這樣被再一次讀入:
- QValueList<QRect> l; str >> l;
小結:QT核心編程之Qt模板庫的內容介紹完了,希望本篇能夠幫助你有效學習,更多內容,在編輯推薦進行參考。
【編輯推薦】