MFC數組模板類CArray

      MFC的數組類支持的數組類似於C++中的常規數組,可以存放任何數據類型。C++的常規數組在使用前必須將其定義成能夠容納所有可能需要的元素,而MFC數組類創建的對象可以根據需要動態地增大或減小,數組的起始下標是0,而上限可以是固定的,也可以隨着元素的增加而增加,數組在內存中的地址仍然是連續分配的。
  MFC定義了數組模板類CArray,並針對各種常用變量類型定義了CByteArray,CWordArray,CUIntArray,CDWordArray,CStringArray,CObArray,CPtrArray。詳見下表:
數組類 變量類型 變量數值範圍 頭文件
CArray 通過模板類的參數類型設定各種類型   Afxtempl.h
CByteArray 8位無符號整數 BYTE類型 0—255 Afxcoll.h
CWordArray 16位無符號整數 WORD類型 0—65535 Afxcoll.h
CDWordArray 32位無符號整數 DWORD類型 0—4294967295 Afxcoll.h
CUIntArray 32位無符號整數 UINT類型 0—4294967295 Afxcoll.h
CStringArray CString字符串 string字符串   Afxcoll.h
CObArray CObject類及其派生類   Afxcoll.h
CPtrArray void* 類型指針   Afxcoll.h

  邊界   
  GetSize()   返回數組大小   
  GetUpperBound()   返回數組上界   
  SetSize()   設設置數組長度   
    
  操作   
  FreeExtra()   釋放已申請但沒有使用的多餘內容   
  RemoveAll()   清空數組     
    
  元素訪問   
  GetAt()   返回數組中指定位置的值   
  SetAt()   設置數組中指定位置的值   
    
  ElementAt   返回數組中指定位置的臨時引用   
  GetData   以指針形式返回數組   
    
  增長數組   
  SetAtGrow   設置數組的增長幅度     
  Add   向數組添加元素   
  Append   將其它數組添加到本數組   
  Copy   將其它數組複製到本數組   
    

  插入刪除   
  InsertAt   向數組插入元素或其它數組   
  RemoveAt   從數組中刪除元素   
    
  操作符   
  operator   []   支持以數組方式訪問   

CByteArray ba;

  ba.Add(66);   
  ba.Add(65);   
  ba.InsertAt(1,69);   
    
  ba.RemoveAt(2);   
  BYTE   i   =   ba[1];   
  ba.RemoveAll();   

MFC數組類使用方法基本相同,下面分別以CArrayCUIntArray爲例演示說明數組類的使用方法。

1 使用 CArray 

打開VC++ 6.0,創建基於對話框的工程ArrayCArrayDlg類聲明文件(ArrayDlg.h)中添加語句: #include <afxtempl.h>請記住:使用CArray一定要包含頭文件afxtempl.h。 

打開主對話框資源IDD_ARRAY_DIALOG,添加一個按鈕IDC_ARRAY_CPOINT,標題爲CArray_CPoint,雙擊該按鈕,在OnArrayCpoint()函數中添加如下代碼: 

void CArrayDlg::OnArrayCpoint()
{
CArray<CPoint,CPoint&> m_Array;
m_Array.SetSize(10,10);
CPoint pt1(10,10);
m_Array.Add(pt1);
CPoint pt2(10,50);
m_Array.Add(pt2);
CPoint pt3(10,100);
m_Array.Add(pt3);
int size=m_Array.GetSize();
CClientDC dc(this);
dc.MoveTo(0,0);
CPoint pt;
for(int i=0;i<size;i++)
{
pt=m_Array.GetAt(i);
dc.LineTo(pt);
}
}

代碼簡要說明: 

CArray <CPoint,CPoint&> m_Array;

該語句定義一個CArray數組對象,模板類CArray有兩個參數,第一個參數爲數組元素的類型,該例中是CPoint,即m_Array是 CPoint數組;第二個參數爲引用類型,一般有兩種選擇,一種選擇與第一個參數類型相同,它意味着數組對象作爲參數傳遞時,傳遞的是數組對象。第二種選擇是第一個參數類型的引用,它意味着數組對象作爲參數傳遞時,傳遞的是數組對象的指針。因此,尤其對於較複雜的數組結構類型,推薦使用引用傳遞,節約內存同時加快程序運行速度,正如本例使用的是CPoint&。 

m_Array.SetSize(10,10);

SetSize函數設定數組的大小,該函數有兩個參數,第一個參數設定數組的大小;第二個參數設定數組增長時內存分配的大小,缺省值是-1,使用缺省值可以保證內存分配得更加合理。本例中第二個參數是10,意即增加一個數組元素會分配10個元素大小的內存供數組使用。

您可以隨時使用SetSize函數設定數組的大小,如果第一個參數值小於數組已有成員數量,多於第一個參數值的成員將被截去並釋放相應內存。    在使用CArray數組前,最好先使用SetSize確定其大小並申請存儲空間。如果不這樣做,向數組中增加元素時,需要不斷地移動和拷貝元素造成運行的低效率和內存碎塊。 

Add函數添加數組元素。 

    m_Array.Add(pt1);

GetSize返回數組元素的數目。 

     int size=m_Array.GetSize();

爲了直觀顯示,該段代碼將各數組元素作成折線畫到屏幕上,其中GetAt(int index)通過index值得到相應的元素值。編譯並運行程序,觀察運行結果。

for(int i=0;i<size;i++)
   {
    pt=m_Array.GetAt(i);
    dc.LineTo(pt);
   }

再次打開主對話框資源IDD_ARRAY_DIALOG,添加一個按鈕IDC_ARRAY_CSTRING,標題爲CArray_CString,雙擊該按鈕,   在OnArrayCstring ()函數中添加如下代碼: 

void CArrayDlg::OnArrayCstring()
{
CArray<cstring,cstring&> m_string;
CString sztiger("tiger");
CString szbear("bear");
CString szdog("dog");
m_string.SetAtGrow(0,sztiger);
m_string.SetAtGrow(2,szdog);
m_string.InsertAt(1,szbear);
int count=m_string.GetSize();
CClientDC dc(this);
dc.SetBkMode(TRANSPARENT);
TEXTMETRIC textMetric;
dc.GetTextMetrics(&textMetric);
int fontHeight=textMetric.tmHeight;
int displayPos=10;
for(int x=0;x<count;++x)
{
dc.TextOut(10,displayPos,m_string[x]);
displayPos+=fontHeight;
}
AfxMessageBox("Continue...");
m_string.RemoveAt(2);
count=m_string.GetSize();
for(x=0;x<count;++x)
{
dc.TextOut(10,displayPos,m_string[x]);
displayPos+=fontHeight;
}
AfxMessageBox("A string has delete,continue...");
m_string.RemoveAll();
count=m_string.GetSize();
if(count==0)
AfxMessageBox("All elements are deleted.");
}
Carray<cstring,cstring&> m_string;

代碼簡要說明: 

m_string.SetAtGrow(2,szdog);

SetAtGrow有兩個參數,第一個參數決定數組元素的序號值,第二個參數是元素的值。該函數根據序號值設置相應數組元素的值,功能與SetAt相近,不同之處是使用該函數設置元素值時,如果序號值大於數組的上界,數組會自動增長。  編譯運行程序,細心的讀者您可能會看到,第一行字符是“tiger”,第二行字符是“bear”,這是我們預料之中的,但第三行是空串,第四行是“dog”。空串是怎樣造成的呢?細分析下面三行代碼就可以知道: 

m_string.SetAtGrow(0,sztiger);
    m_string.SetAtGrow(2,szdog);
    m_string.InsertAt(1,szbear);

第一行設定元素0“tiger”,這是沒有疑義的。第二行設定元素2“dog”,但是在設定元素2的同時自動將元素1填充爲空串。第三行插入“bear”爲元素1,同時原來的元素1和元素2後移爲元素2和元素3

怎麼樣,這回明白了吧。

m_string.InsertAt(1,szbear);

InsertAt函數在指定序號處插入相應元素,該函數在執行過程中,插入點後面的元素會自動後移。 dc.TextOut(10,displayPos,m_string[x]);其中,m_string[x]是數組類對操作符[]的重載,數組類CArray允許使用[]操作符,類似於C++的常規數組。m_string[x]也可以用m_string.GetAt(x)替代。 

m_string.RemoveAt(2);

RemoveAt只有一個參數,即元素序號值。該函數根據元素序號值刪除相應元素值,後面的元素會自動前移。 

m_string.RemoveAll();

RemoveAll刪除所有元素值

2演示使用CUIntArray

打開主對話框資源IDD_ARRAY_DIALOG,添加一個按鈕IDC_CUINTARRAY,標題爲CUIntArray,雙擊該按鈕,在OnCuintarray ()函數中添加如下代碼:

這部分代碼不作說明,請讀者自行分析。

最後再說明一點:RemoveAtInsertAt函數操作時會使得數組元素移位,運行時間大於SetAtRemoveAllAdd函數。 

希望這篇文章能對您有所幫助。

void CArrayDlg::OnCuintarray()
{
CUIntArray m_array;
m_array.SetSize(5,5);
m_array.SetAt(0,0);
m_array.SetAt(1,1);
m_array.SetAt(2,2);
m_array.SetAt(3,3);
m_array.SetAt(4,4);
int count=m_array.GetSize();
CClientDC dc(this);
dc.SetBkMode(TRANSPARENT);
TEXTMETRIC textMetric;
dc.GetTextMetrics(&textMetric);
int fontHeight=textMetric.tmHeight;
int displayPos=10;
for(int x=0;x<count;++x)
{
CString str;
str.Format("%d",m_array.GetAt(x));
dc.TextOut(10,displayPos,str);
displayPos+=fontHeight;
}
}

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