sequentail Containers

sequentail Containers
QVector<T>
array-like data structure(在尾部插入數據時效率很高,而在中間和頭部插入數據時開銷很大)。
QVector提供了[]運算符
QVector可以用<<運算符代替append()函數。
QVector中的基本類型及指針被初始化爲0。
QLinkedList<T>
QLinkedList不提供[]運算符,所以必須通過迭代器來對其進行遍歷。
QList<T> array-list:綜合了QVector<T>和QLinkedList<T>最重要的優點: 支持[]運算符
在頭部或尾部的插入/刪除操作很迅速,而尺寸在1000以下時,在中間的插入/刪除操作也很迅速。
通常情況下,QList是最合適的通用型容器。
QStringList : QList<QString>的子類,在Qt中的API中被廣泛使用
QStack<T> 和QQueue< T>是Qt提供的兩個convenience subclasses,QStack<T>實際上是一個額外提供了push(),pop()top()接口的QVector,而 QQueue<T>實際是一個額外提供了enqueue()和dequeue()和head()的QList。
容器中可以放置的類必須擁有default constructor、copy constructor 和 assignment operator(顯式定義或由編譯器生成)
注意,派生自QObject的類不符合上述要求,因爲其不具備copy constructor和assignment operator;解決方法是在容器中存儲對象指針而不是對象本身。
容器中所存放的元素本身也可以是容器,即可以嵌套——不過需要注意將連續的尖括號用空格分隔開,以免編譯器誤認爲>>運算符。
Iterator
Qt支持兩種風格的迭代 器—— Java- style和STL- style
Java-style的迭代器更容易使用,而STL-style的迭代器可以同Qt和STL中的算法聯合使用,更爲強大。
Java-style Iterator
每個sequential容器類,都有兩個Java-style的迭代器類型:只讀迭代器和讀寫迭代器。
在使用Java-style的迭代器時,要清楚的第一件事情就是:迭代器並不直接指向容器中的元素,而是指向元素之前或之後的位置。迭代器被初始化時指向 容器中第一個元素之前;若迭代器的右側有元素存在,hasNext()函數返回true;next()函數返回位於迭代器右側的元素,並將迭代器向右方移 動一個元素的位置;hasPrevious()和previous()函數執行反方向的操作。
remove()函數總是刪除最近一次被跳過的那個元素。
setValue()函數總是對最近一次被跳過的那個元素執行更新操作
insert()函數在迭代器當前指向的位置處插入新元素,並將迭代器指向新元素及其後續元素之間的位置。
STL-style Iterator
每個sequential容器類,都有兩個STL-style的迭代器類型:Container<T>::iterator和 Container<T>::const_iterator。
容器的begin()函數返回一個指向容器中頭部元素的iterator,而end()返回指向容器中尾部元素之後位置的 iterator;
在容器爲空時,begin()和end()的結果相同。
通常通過調用isEmpty()來檢查容器是否爲空,而不是通過比較begin()和end()的結果。
可以對STL-style的 iterator使用+、-、*這三個運算符,類似於指針的用法。
某些Qt函數的返回值是容器類;如果需要使用STL-style的迭代器來對這樣的返回值進行遍歷,必須保存返回值的一個副本,並在副本上 完成遍歷,否則會可能會導致所謂的"dangling iterator"。
注意,若使用java-style的只讀迭代器,在這種情況下會隱式的完成複製的工作,保證迭代器總是在副本上進行遍歷操作。
implicit sharing(copy on write)
Qt中的implicit sharing機制的美妙之處在於它鼓勵程序員在返回對象時採用傳值這種簡明的方式而不是引用或指針。
STL與此相反,鼓勵程序員使用non-const引用來傳遞vector以避免將函數返回值的複製開銷。
Qt中所有的容器都採用了implicit sharing機制;此外很多其他類QByteArray,QBrush,QFont,QImage,QString也採用了該機制——這保證這些類在以 傳值方式進行傳遞時有很高的效率,無論是作爲參數還是函數返回值。
在Qt提供的implicit sharing機制下,對vector或list執行只讀操作時,採用at()而不是[]運算符是一個更好的選擇。
類似的,儘可能的使用constBegin()和constEnd()以避免不必要的拷貝操作。
foreach syntax
foreach在進入循環體時自動複製容器的副本並在此副本上進行迭代,因此如果迭代過程中有通過迭代器對容器的修改操作的話,並不會影響循環的進行,循 環結束後容器的內容也不會發生變化。
當然,如果在foreach循環中直接使用[]運算符對容器進行寫操作的話,容器內容自然會發生變化。
foreach中支持break和continue語句
Associative Containers
QMap
QMap中的key-value對是升序排列的
插入和刪除操作中都可以使用[]運算符,其下標爲key;爲避免創建不必要的空值,推薦用vlaue()而不是[]從QMap中取值。
QMap<K,T>中的K和T除了要求具備默認構造函數、拷貝構造函數和賦值運算符外,K還必須支持operator <,因爲這樣才能實現前面提到的升序排列。
keys() & values()
QMap的特性是單值;QMultiMap<K,T>則支持同一關鍵字下多值的存在,插入操作由insertMulti()完成
QHash
QHash提供的接口和QMap很相似
QHash<K,T>中的K要符合的額外要求:支持operator ==,並且K可用全局函數qHash()來計算hash value
QHash通常是單值的,而QMultiHash則通過insertMulti()支持多值插入。
QCache<K,T> & QSet<K>
遍歷associative containr的最簡單方法是使用Java-style的迭代器
foreach syntax也可用於assocaitive container
Generic Algorithms
頭文件<QAlgorithms>中聲明瞭一組全局模板函數,用於實現作用於容器的基本算法;多數算法都通過STL- style的迭代器來完成。
STL頭文件<algorithm> 中的函數,即可作用於Qt容器,也可作用於STL容器。
qFind(),qBinaryFind(),qFill(),qCopy(),qSort(),qStableSorg(),qDeleteAll(),qSwap()
需要注意的是,qDeleteAll()只對包含指針的容器有意義,該函數將釋放所有對象,但並不刪除容器中的指針。
Strings,Byte Arrays,and Variants
QString,QByteArray和QVariant這三個類和容器類有很多相似之處,在某些場合下可作爲容器類的替代品;和容器類一樣,這三個類也 應用了implicit sharing 機制
QString
QString中存放的是16-bit的Unicold值。
從概念上,QString可以看成是QVector<QChar>。
QString提供+/+=運算符以及append()函數用於合併字符串
QString提供的sprintf()函數,與C++標準庫中的sprintf支持相同的參數格式。
QString提供的arg()函數,是比sprintf()更好的選擇,因爲它保證類型安全,支持unicode。
QString::number(): number->string
QString::setNum(): number->string
反向的轉換接口:toInt(),toLongLong(),toDouble()等,這些函數都有一個可選參數——bool類型的指針,若轉換失敗則將 該bool變量置爲true,否則置false.
mid()函數返回指定區間內的子串;left()和right()函數則分別返回左子串和右子串
QString的indexOf()函數可用於文本匹配,返回所匹配子串的起始下標;匹配失敗時返回值爲-1。
startsWith()和endsWith()函數可用於判斷字符串的首部和尾部是否符合某種模式。
QString在進行比較時是大小寫敏感的;當所比較的字符串是用戶可見時,使用localeAwareCompare()通常是正確的選擇。
toLower() & toUpper()
replace() & remove() & insert()
trimmed() & simplified()——這兩個函數用於消去字符串中的whitesapce(spaces,tabs,newlines等)
QString::split()將一個字符串分割爲子串,並返回由這些子串們組成的一個QStringList。
QStringList中的所有元素可以通過join()函數組成一個新的字符串,join()的參數在合併時會被插入相鄰元素中間。
在大多數情況下,由const char * 至QString的轉換是自動的。
反方向的轉換,可通過toAscii()或toLatin1()來完成;這些函數返回一個QByteArray,其可以通過QByteArray ::data 或QByteArray::constData()來轉換爲const char * ;
爲了簡化轉換,Qt提供了一個qPrintable()宏用於完成與toAscii()以及constData()相同的操作。
QByteArray
QByteArray提供的API與QString的很相似。
QByteArray的用處在於存儲原始2進制數據及8-bit編碼的字符串。

通常選擇QString而不是QByteArray來存儲文本信息,因爲QString支持Unicode。
QByteArray會自動在最後一個元素之後補上‘/0',這樣使得將QByteArray傳遞給需要const char *的函數變得很容易。
QByteArray支持'/0',允許存儲任意的2進制數據。
QVariant
QVariant類可用於存放很多Qt類型的值,並且還可以存放容器。
QVariant在 item view class,database model 和QSetting中被廣泛的使用着。
利用QVariant和嵌套,可以創建非常複雜的數據結構。
QVariant的便利性是以性能和代碼的可讀性爲代價的。
QVariant被Qt的meta-object system所使用,因此是Qtcore module的組成部分。
QVariant也可以支持用戶自定義的數據類型,前提是該類型具有defalut constructor和copy constructor。要實現對用戶自定義類型的支持,需要使用宏Q_DECLARE來註冊該類型。
全局函數:qVariantFromValue(),qVariantValue<T> (),qVariantCanConvert<T>()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章