How to: 建立型別安全集合
本文說明如何製作您自己的資料型別的型別安全集合。 主題包括:
使用樣板式類別型別安全
實作 helper 函式
使用非樣板集合類別
Mfc 程式庫提供以 C++ 樣板為基礎的預先定義型別安全集合。 因為它們是範本時,這些類別可幫助提供型別安全和方便使用不具型別轉型和其他額外的工作中使用非樣板類別,為上述目的。 MFC 範例收集示範使用 MFC 應用程式中的樣板式集合類別。 一般情況下,您撰寫新的集合程式碼的任何時候使用這些類別。
使用樣板式類別型別安全
若要使用樣板式類別
宣告集合類別型別的變數。 例如:
CList<int, int> m_intList;
呼叫成員函式的集合物件。 例如:
m_intList.AddTail(100); m_intList.RemoveAll();
如果有必要,請實作 helper 函式 和 SerializeElements。 如需實作這些函式的詳細資訊,請參閱實作的 Helper 函式。
這個範例會顯示一個整數串列的宣告。 在步驟 1 中的第一個參數是儲存為清單中的元素資料型別。 第二個參數指定如何將資料傳遞至,且所傳回的成員函式的集合類別,例如新增和GetAt。
實作 Helper 函式
樣板式集合類別CArray, CList,以及CMap使用視需要為您的衍生的集合類別,您可以自訂的五個通用的 helper 函式。 如需這些協助程式函式的詳細資訊,請參閱集合類別的協助程式 在 MFC 參考手冊 》。 序列化函式的實作是所需的大多數使用樣板式集合類別。
序列化項目
CArray, CList,以及CMap類別呼叫SerializeElements儲存集合的項目,或從封存中讀取它們。
預設實作的SerializeElements helper 函式不執行位元的寫入會從物件到保存檔,或位元從保存讀取的物件,取決於是否物件會被儲存在資料庫或從封存擷取。 覆寫SerializeElements如果此巨集指令不適用。
如果您的集合會儲存衍生自物件CObject ,大膽建議您使用IMPLEMENT_SERIAL集合項目類別的實作中的巨集,您可以利用內建的序列化功能CArchive和CObject:
CArray< CPerson, CPerson& > personArray;
template <> void AFXAPI SerializeElements <CPerson> (CArchive& ar,
CPerson* pNewPersons, INT_PTR nCount)
{
for (int i = 0; i < nCount; i++, pNewPersons++)
{
// Serialize each CPerson object
pNewPersons->Serialize(ar);
}
}
插入多載的運算子的CArchive呼叫CObject::Serialize (或該函式的覆寫) 為每個 CPerson 物件。
使用非樣板集合類別
MFC 也支援 MFC 1.0 版起所引進的集合類別。 這些類別無法以範本為基礎。 可用於包含支援型別的資料CObject*, UINT, DWORD,以及CString。 您可以使用這些預先定義的集合 (例如CObList) 來儲存衍生自的任何物件的集合CObject。 MFC 也提供其他預先定義的集合,來保存基本型別,例如 UINT 與 void 指標 (void1)。 一般情況下,不過,通常很有幫助定義您自己,無法保留的具體的類別和其系出物件的型別安全集合。 請注意執行這項作業的集合類別無法以範本為基礎比使用樣板式類別更多的工作。
有兩種方式來建立型別安全集合,與非樣板式集合:
使用非樣板式集合,如有必要的型別轉型。 這是比較簡單的作法。
從衍生並擴充非樣板型別安全集合。
若要使用非樣板集合和轉換型別
使用其中一個非樣板類別,例如CWordArray、 直接。
比方說,您可以建立CWordArray並加入任何 32 位元值,然後將其擷取。 所以沒有需這樣做。 您只要使用預先定義的功能。
也可以使用預先定義的集合,例如CObList、,無法保留任何物件衍生自CObject。 A CObList集合定義來容納指標CObject。 當您從清單中擷取物件時,您可能要轉型為適當的型別,因為結果CObList函數會傳回指標CObject。 比方說,如果您儲存CPerson中的物件CObList集合中,您必須將轉換擷取的項目是變數的指標, CPerson物件。 下列範例會使用CObList的集合來儲存CPerson物件:
CPerson* p1 = new CPerson(); CObList myList; myList.AddHead(p1); // No cast needed CPerson* p2 = (CPerson*)myList.GetHead();
使用預先定義的集合型別,以及在需要時轉換的這項技術可能適用於您的集合所需的許多。 如果您需要進一步的功能或多個型別安全,以範本為基礎的類別,或依照下一個程序。
若要衍生並擴充非樣板型別安全集合
其中一個預先定義的非樣板類別衍生您自己的集合類別。
當您衍生類別時,您可以將提供給現有的函式的型別安全介面的型別安全的包裝函式。
比方說,如果您衍生清單從CObList來保留CPerson物件,您可以加入包裝函式AddHeadPerson和GetHeadPerson,如下所示。
class CPersonList : public CObList { public: void AddHeadPerson( CPerson* person ) {AddHead( person );} const CPerson* GetHeadPerson() {return (CPerson*)GetHead();} };
這些包裝函式提供的型別安全的方法來加入或擷取CPerson衍生的串列中的物件。 您所見,如GetHeadPerson函式,您只需正在封裝型別轉型。
您也可以定義新的函式,來擴充集合的功能,而非只包裝在型別安全的包裝函式中的既有的功能,以新增新功能。 比方說,文件 CObject 集合中刪除所有物件告訴您,來刪除清單中包含的所有物件的函式。 做為成員函式時,無法加入此函式在衍生類別。