加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 什么是QList<T>
    • 實戰(zhàn)例子
    • 總結(jié)一下
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

QT容器很香之QList<T>實戰(zhàn)舉例

2021/08/13
664
閱讀需 6 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

大家好,我是逸珺。今天來聊一下QList,QList 是一種QT容器,如果能熟練使用它,會非常香。

什么是QList<T>

QList<T> 是QT中通用容器類,它將對象存儲在一個表中,該表提供基于索引的快速訪問和基于索引的插入和刪除。熟悉C++標準庫的話,就類似于std:list<T> ,為什么這里描述是跟了一個<T>呢?因為是容器類,所謂容器,就把它想象成一個能裝東西的框,但是這與現(xiàn)實生活中的框還是有區(qū)別的,現(xiàn)實中的框可以隨便往里面裝東西,先裝幾個土豆,再放兩顆白菜,再放一本書....,隨便裝,只要放的下。

但是,這個容器類跟的這個<T>,是指泛型,從字面意思上看,好像也是什么對象都可以往里面放,但是這么幾層需要理解:

  • 對于特定的容器,需要指明其可裝進去的對象類型對于特定的容器,只能裝指定的類型

那么,為什么又說是泛型呢?就是說不同的QList對象,根據(jù)所指定的T的類型,可以裝各自不同類型的對象,比如:

QList<float> m_list1;
QList<int>  m_list2;

m_list1可以存float型的對象,而m_list2則可以裝int型對象。這是怎么做到的呢,是C++編譯器在編譯期根據(jù)T本身類型編譯綁定的。

前面說QList是基于索引插入和刪除的容器類,何以見得呢?來看看QT官方文檔例子:

QList<QString> list = { "one", "two", "three" };

這意味著這三個元素是這樣放的:

 

實戰(zhàn)例子

假設有這么一個需求,利用一個socket接收一個設備的計算數(shù)據(jù),每一個計算數(shù)據(jù)是這樣的:

typedef struct _t_measure {
  qint64 addr;
  qint64 Real;
  qint64 Imag;
  qint64 rms;
}t_measure;

在類中加入QList<T>,這里T是t_measure:

QList<t_measure> m_measure;

一個報文里面有多個測量結(jié)果,QT寫的應用程序,需要一邊收一邊顯示或者存儲,接收可能是一個線程,或者sokect消息回調(diào)函數(shù),比如是UDP接收的:

connect(m_MeasureUdpSocket, SIGNAL(readyRead()),
        this, SLOT(readMeasurement()));

接收函數(shù):

#define MAX_BUF_SIZE        (300)
#define MAX_BUF_SIZE_BYTES  (MAX_BUF_SIZE*8)
void Measurement::readMeasurement()
{
  typedef union _u_buf {
    char  buf[MAX_BUF_SIZE_BYTES];
    qint64 dpts[MAX_BUF_SIZE];
  }u_buf;

  u_buf buffer;
  t_measure *pRaw=nullptr;
  int len = 0;
  while (m_MeasureUdpSocket->hasPendingDatagrams()) {
    len = m_MeasureUdpSocket->pendingDatagramSize();
    if(len>MAX_BUF_SIZE_BYTES)
       len = MAX_BUF_SIZE_BYTES;
      
    m_MeasureUdpSocket->readDatagram(buffer.buf, len);
    if(buffer.dpts[0]==0x7FAAAAF7CCCCCCCC) {
      pRaw = (t_measure *)&buffer.dpts[2];
      for(int i=0;i<buffer.dpts[1];i++) {
         m_measure.append(*pRaw);
         pRaw++;
      }
    }
  }
}

假設定義一個頭部標識為0x7FAAAAF7CCCCCCCC, 頭部正確,然后按照長度不斷將接收到的數(shù)據(jù)追加到表的尾部。

在另一個地方可以從頭部不斷取出數(shù)據(jù)進行后續(xù)處理,比如進行進一步計算,顯示或存儲,比如:

  if(m_measure.isEmpty()) {
    return;
  }

  int pts = m_measure.size();
  t_measure temp;
  for(int i=0;i<pts;i++) {
    temp = m_measure.takeFirst();
    
    //做后續(xù)處理
    ......
  }

上述例子,用一個示意圖描述,大概就是下面這樣:

接收端不斷在尾部追加,而處理端則在頭部取出,就是一個FIFO操作。

如果不使用QList<T>,自己實現(xiàn)一個FIFO則需要考慮很多細節(jié)問題,所以使用C++,或者QT要盡量擺脫C語言的編程習慣,盡量使用已有的輪子,這會大大提高生產(chǎn)效率。

總結(jié)一下

使用C++,熟悉掌握容器這些泛型編程方法,不用自己去管理這些底層實現(xiàn),會大大提高效率。我覺得蠻香,你覺得呢?

—— The End ——

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

嵌入式客棧,主要分享嵌入式Linux系統(tǒng)構(gòu)建、嵌入式Linux驅(qū)動開發(fā)、單片機技術(shù)、FPGA開發(fā)、信號處理、工業(yè)通訊等技術(shù)主題。歡迎關(guān)注,一起交流,共同進步!